COP4610: Operating Systems & Concurrent Programming up ↑

Tools for Understanding & Debugging the Compilation Process

 

Generating Assembly Code with gcc

There will be times when you may want to look at the assembly language code that is generated by a compiler. This can be helpful in understanding whether code is likely to be safe for concurrent execution. On rare occasions when a program is failing for no apparent reason, it may also be helpful in determining whether the failure is due to a compiler defect that is causing incorrect machine code to be generated.

With the gcc compiler, you can obtain a listing of the assembly language generated by the compiler by using the -s option. For example, "gcc -c -S filename.c" will produce the assembly language code on file filename.s.

Suppose the file filename.c contained the following code:

int f (int n) {
  if (n < 2) return n;
  return f (n - 1) * n;
}

Compiling this with gcc -c -s filename.c on an Intel Pentium platform produced the following code:

   .file   "filename.c"
        .version        "01.01"
gcc2_compiled.:
.text
        .align 4
.globl A
        .type    A,@function
A:
        pushl   %ebp
        movl    %esp, %ebp
        movl    $1, X
        movl    $1, %eax
        .p2align 2
.L5:
        testl   %eax, %eax
        jne     .L5
        popl    %ebp
        ret
.Lfe1:
        .size    A,.Lfe1-A
        .comm   X,4,4
        .ident  "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-81)"

Viewing Preprocessed Code with gcc

There will be times when you want to see what the C preprocessor did, by way of macro expansions and header files. This is sometimes the only way to debug problems with macro definitions, and problems with #include and #ifdef directives.

With the gcc compiler, you can obtain a listing of the source code just after it has been preprocessed, (i.e. after all macros have been expanded, and after all #include and #ifdef directives have been processed, just as the code is ready to go to the compiler-proper. You do this you use the -E option. For example, "gcc -c -E filename.c > filename.lst" will produce the preprocessed code on the file filename.lst. You may then examine it with a text editor.

Suppose the file "filename.c" contains the following text:

#ifdef YY
#define XXXX XX
#else
#define XXXX ZZZZZZZ
#endif
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The output from gcc -E filename.c< would be as follows:

# 6 "testit.c"
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ZZZZZZZ
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  
T. P. Baker. ($Id)