tags:

views:

144

answers:

3

What is the best and easiest method to debug optimized code on Unix which is written in C?

Sometimes we also don't have the code for building an unoptimized library.

+3  A: 

This is a very good question. I had similar difficulties in the past where I had to integrate 3rd party tools inside my application. From my experience, you need to have at least meaningful callstacks in the associated symbol files. This is merely a list of addresses and associated function names. These are usually stripped away and from the binary alone you won't get them... If you have these symbol files you can load them while starting gdb or afterward by adding them. If not, you are stuck at the assembly level...

One weird behavior: even if you have the source code, it'll jump forth and back at places where you would not expect (statements may be re-ordered for better performance) or variables don't exist anymore (optimized away!), setting breakpoints in inlined functions is pointless (they are not there but part of the place where they are inlined). So even with source code, watch out these pitfalls.

I forgot to mention, the symbol files usually have the extension .gdb, but it can be different...

jdehaan
A: 

Write small code samples by the same interfaces (something in its header), and call your samples instead of that optimized code, say simulation, to narrow down the code scope which you debug. Furthermore you are able to do error enjection in your samples.

EffoStaff Effo
yes but if it includes several hundred of c files for building one executable and i am debugging that executable.it would be head ache:(
Vijay Sarathi
the samples size (how many lines in total) is up to you, and now you can just use debuger (i.e. gdb) because have all source code.
EffoStaff Effo
+1  A: 

This question is not unlike "what is the best way to fix a passenger car?"

The best way to debug optimized code on UNIX depends on exactly which UNIX you have, what tools you have available, and what kind of problem you are trying to debug.

Debugging a crash in malloc is very different from debugging an unresolved symbol at runtime.

For general debugging techniques, I recommend this book.

Several things will make it easier to debug at the "assembly level":

  • You should know the calling convention for your platform, so you can tell what values are being passed in and returned, where to find the this pointer, which registers are "caller saved" and which are "callee saved", etc.
  • You should know your OS "calling convention" -- what a system call looks like, which register a syscall number goes into, the first parameter, etc.
  • You should "master" the debugger: know how to find threads, how to stop individual threads, how to set a conditional breakpoint on individual instruction, single-step, step into or skip over function calls, etc.

It often helps to debug a working program and a broken program "in parallel". If version 1.1 works and version 1.2 doesn't, where do they diverge with respect to a particular API? Start both programs under debugger, set breakpoints on the same set of functions, run both programs and observe differences in which breakpoints are hit, and what parameters are passed.

Employed Russian
I usaully face a issues by a crash and i am working on AIX platform.And in my working environment only dbx is available.some times it shows me wrong values of line numbers and some times i do see soem garbage values as the arguments in the function calls.this confuses me a lot.
Vijay Sarathi