Go to the first, previous, next, last section, table of contents.


Copyright (C) 1992, 93, 94, 95, 97, 1998 Free Software Foundation, Inc. Contributed by Cygnus Support.

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Overview of Stabs

Stabs refers to a format for information that describes a program to a debugger. This format was apparently invented by Peter Kessler at the University of California at Berkeley, for the pdx Pascal debugger; the format has spread widely since then.

This document is one of the few published sources of documentation on stabs. It is believed to be comprehensive for stabs used by C. The lists of symbol descriptors (see section Table of Symbol Descriptors) and type descriptors (see section Table of Type Descriptors) are believed to be completely comprehensive. Stabs for COBOL-specific features and for variant records (used by Pascal and Modula-2) are poorly documented here.

Other sources of information on stabs are Dbx and Dbxtool Interfaces, 2nd edition, by Sun, 1988, and AIX Version 3.2 Files Reference, Fourth Edition, September 1992, "dbx Stabstring Grammar" in the a.out section, page 2-31. This document is believed to incorporate the information from those two sources except where it explicitly directs you to them for more information.

Overview of Debugging Information Flow

The GNU C compiler compiles C source in a `.c' file into assembly language in a `.s' file, which the assembler translates into a `.o' file, which the linker combines with other `.o' files and libraries to produce an executable file.

With the `-g' option, GCC puts in the `.s' file additional debugging information, which is slightly transformed by the assembler and linker, and carried through into the final executable. This debugging information describes features of the source file like line numbers, the types and scopes of variables, and function names, parameters, and scopes.

For some object file formats, the debugging information is encapsulated in assembler directives known collectively as stab (symbol table) directives, which are interspersed with the generated code. Stabs are the native format for debugging information in the a.out and XCOFF object file formats. The GNU tools can also emit stabs in the COFF and ECOFF object file formats.

The assembler adds the information from stabs to the symbol information it places by default in the symbol table and the string table of the `.o' file it is building. The linker consolidates the `.o' files into one executable file, with one symbol table and one string table. Debuggers use the symbol and string tables in the executable as a source of debugging information about the program.

Overview of Stab Format

There are three overall formats for stab assembler directives, differentiated by the first word of the stab. The name of the directive describes which combination of four possible data fields follows. It is either .stabs (string), .stabn (number), or .stabd (dot). IBM's XCOFF assembler uses .stabx (and some other directives such as .file and .bi) instead of .stabs, .stabn or .stabd.

The overall format of each class of stab is:

.stabs "string",type,other,desc,value
.stabn type,other,desc,value
.stabd type,other,desc
.stabx "string",value,type,sdb-type

For .stabn and .stabd, there is no string (the n_strx field is zero; see section Symbol Information in Symbol Tables). For .stabd, the value field is implicit and has the value of the current file location. For .stabx, the sdb-type field is unused for stabs and can always be set to zero. The other field is almost always unused and can be set to zero.

The number in the type field gives some basic information about which type of stab this is (or whether it is a stab, as opposed to an ordinary symbol). Each valid type number defines a different stab type; further, the stab type defines the exact interpretation of, and possible values for, any remaining string, desc, or value fields present in the stab. See section Table of Stab Types, for a list in numeric order of the valid type field values for stab directives.

The String Field

For most stabs the string field holds the meat of the debugging information. The flexible nature of this field is what makes stabs extensible. For some stab types the string field contains only a name. For other stab types the contents can be a great deal more complex.

The overall format of the string field for most stab types is:

"name:symbol-descriptor type-information"

name is the name of the symbol represented by the stab; it can contain a pair of colons (see section Defining a Symbol Within Another Type). name can be omitted, which means the stab represents an unnamed object. For example, `:t10=*2' defines type 10 as a pointer to type 2, but does not give the type a name. Omitting the name field is supported by AIX dbx and GDB after about version 4.8, but not other debuggers. GCC sometimes uses a single space as the name instead of omitting the name altogether; apparently that is supported by most debuggers.

The symbol-descriptor following the `:' is an alphabetic character that tells more specifically what kind of symbol the stab represents. If the symbol-descriptor is omitted, but type information follows, then the stab represents a local variable. For a list of symbol descriptors, see section Table of Symbol Descriptors. The `c' symbol descriptor is an exception in that it is not followed by type information. See section Constants.

type-information is either a type-number, or `type-number='. A type-number alone is a type reference, referring directly to a type that has already been defined.

The `type-number=' form is a type definition, where the number represents a new type which is about to be defined. The type definition may refer to other types by number, and those type numbers may be followed by `=' and nested definitions. Also, the Lucid compiler will repeat `type-number=' more than once if it wants to define several type numbers at once.

In a type definition, if the character that follows the equals sign is non-numeric then it is a type-descriptor, and tells what kind of type is about to be defined. Any other values following the type-descriptor vary, depending on the type-descriptor. See section Table of Type Descriptors, for a list of type-descriptor values. If a number follows the `=' then the number is a type-reference. For a full description of types, section Defining Types.

A type-number is often a single number. The GNU and Sun tools additionally permit a type-number to be a pair (file-number,filetype-number) (the parentheses appear in the string, and serve to distinguish the two cases). The file-number is a number starting with 1 which is incremented for each seperate source file in the compilation (e.g., in C, each header file gets a different number). The filetype-number is a number starting with 1 which is incremented for each new type defined in the file. (Separating the file number and the type number permits the N_BINCL optimization to succeed more often; see section Names of Include Files).

There is an AIX extension for type attributes. Following the `=' are any number of type attributes. Each one starts with `@' and ends with `;'. Debuggers, including AIX's dbx and GDB 4.10, skip any type attributes they do not recognize. GDB 4.9 and other versions of dbx may not do this. Because of a conflict with C++ (see section GNU C++ Stabs), new attributes should not be defined which begin with a digit, `(', or `-'; GDB may be unable to distinguish those from the C++ type descriptor `@'. The attributes are:

aboundary
boundary is an integer specifying the alignment. I assume it applies to all variables of this type.
pinteger
Pointer class (for checking). Not sure what this means, or how integer is interpreted.
P
Indicate this is a packed type, meaning that structure fields or array elements are placed more closely in memory, to save memory at the expense of speed.
ssize
Size in bits of a variable of this type. This is fully supported by GDB 4.11 and later.
S
Indicate that this type is a string instead of an array of characters, or a bitstring instead of a set. It doesn't change the layout of the data being represented, but does enable the debugger to know which type it is.

All of this can make the string field quite long. All versions of GDB, and some versions of dbx, can handle arbitrarily long strings. But many versions of dbx (or assemblers or linkers, I'm not sure which) cretinously limit the strings to about 80 characters, so compilers which must work with such systems need to split the .stabs directive into several .stabs directives. Each stab duplicates every field except the string field. The string field of every stab except the last is marked as continued with a backslash at the end (in the assembly code this may be written as a double backslash, depending on the assembler). Removing the backslashes and concatenating the string fields of each stab produces the original, long string. Just to be incompatible (or so they don't have to worry about what the assembler does with backslashes), AIX can use `?' instead of backslash.

A Simple Example in C Source

To get the flavor of how stabs describe source information for a C program, let's look at the simple program:

main()
{
        printf("Hello world");
}

When compiled with `-g', the program above yields the following `.s' file. Line numbers have been added to make it easier to refer to parts of the `.s' file in the description of the stabs that follows.

The Simple Example at the Assembly Level

This simple "hello world" example demonstrates several of the stab types used to describe C language source files.

1  gcc2_compiled.:
2  .stabs "/cygint/s1/users/jcm/play/",100,0,0,Ltext0
3  .stabs "hello.c",100,0,0,Ltext0
4  .text
5  Ltext0:
6  .stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
7  .stabs "char:t2=r2;0;127;",128,0,0,0
8  .stabs "long int:t3=r1;-2147483648;2147483647;",128,0,0,0
9  .stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
10 .stabs "long unsigned int:t5=r1;0;-1;",128,0,0,0
11 .stabs "short int:t6=r1;-32768;32767;",128,0,0,0
12 .stabs "long long int:t7=r1;0;-1;",128,0,0,0
13 .stabs "short unsigned int:t8=r1;0;65535;",128,0,0,0
14 .stabs "long long unsigned int:t9=r1;0;-1;",128,0,0,0
15 .stabs "signed char:t10=r1;-128;127;",128,0,0,0
16 .stabs "unsigned char:t11=r1;0;255;",128,0,0,0
17 .stabs "float:t12=r1;4;0;",128,0,0,0
18 .stabs "double:t13=r1;8;0;",128,0,0,0
19 .stabs "long double:t14=r1;8;0;",128,0,0,0
20 .stabs "void:t15=15",128,0,0,0
21      .align 4
22 LC0:
23      .ascii "Hello, world!\12\0"
24      .align 4
25      .global _main
26      .proc 1
27 _main:
28 .stabn 68,0,4,LM1
29 LM1:
30      !#PROLOGUE# 0
31      save %sp,-136,%sp
32      !#PROLOGUE# 1
33      call ___main,0
34      nop
35 .stabn 68,0,5,LM2
36 LM2:
37 LBB2:
38      sethi %hi(LC0),%o1
39      or %o1,%lo(LC0),%o0
40      call _printf,0
41      nop
42 .stabn 68,0,6,LM3
43 LM3:
44 LBE2:
45 .stabn 68,0,6,LM4
46 LM4:
47 L1:
48      ret
49      restore
50 .stabs "main:F1",36,0,0,_main
51 .stabn 192,0,0,LBB2
52 .stabn 224,0,0,LBE2


Go to the first, previous, next, last section, table of contents.