开发者

Optimized code on Unix?

开发者 https://www.devze.com 2022-12-08 02:43 出处:网络
What is the best and easiest m开发者_运维问答ethod to debug optimized code on Unix which is written in C?

What is the best and easiest m开发者_运维问答ethod to debug optimized code on Unix which is written in C?

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


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...


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消