开发者

Why does the debugger need symbols to reconstruct the stack?

When debugging in Visual Studio, if symbols for a call stack are missing, for example:

00 > HelloWorld.exe!my_function(int y=42)  Line 291
01   dynlib2.dll!10011435()  
  [Frames below may be incorrect and/or missing, no symbols loaded for dynlib2.dll] 
02   dynlib2.dll!10011497()  
03   HelloWorld.exe!wmain(int __formal=1, int __formal=1)  Line 297 + 0xd bytes
04   HelloWorld.exe!__tmainCRTStartup()  Line 594 + 0x19 bytes
05   HelloWorld.exe!wmainCRTStartup()  Line 414
06   kernel32.dll!_BaseProcessStart@开发者_开发技巧4()  + 0x23 bytes 

the debugger will display the warning Frames below may be incorrect and/or missing.

(Note that only lines 01 and 02 have no symbols. Line 00, where I set a breakpoint and all other lines have symbols loaded.)

Now, I know how to fix the warning (->get pdb file), what I do not quite get is why it is displayed after all! The stack I pasted above is fully OK, it's just that I do not have a pdb file for the dynlib2.dll module.

Why does the debugger need a symbols file to make sure the stack is correct?


I think this is because not all the functions follow the "standard" stack layout. Usually every function starts with:

push        ebp  
mov         ebp,esp 

and ends with

pop         ebp  
ret

By this every function creates its so-called stack frame. EBP always points to the beginning of the top stack frame. In every frame the first two values are the pointer to the previous stack frame, and the function return address.

Using this information one can easily reconstruct the stack. However:

  1. This stack information won't include function names and parameters info.
  2. Not all the functions obey this stack frame layout. If some optimizations are enabled (/Oy, omit stack frame pointers, for instance) - the stack layout is different.


I tried to understand this myself a while ago.

As of 2013, FPO is not used within MSFT and is generally frowned upon. I did come across a different MS binary technology used internally, that probably hampers naive EBP chain traversal: Basic Block Tools.

As noted in the post, PDBs do include 'StackFrameTypeEnum', and elsewhere it's hinted that they include the 'unwind program' for a stack frame. So all in all, they are still needed, and the gory details of why exactly - are not documented.


Symbols are decoupled from the associated binary code to reduce the size of shipping binaries. Check how big your PDB files are - huge, especially compared to the matching binary file (EXE/DLL). You would not want that overhead every time the binary is shipped, installed and used. This is especially important at load time. The symbol information is only for debugging after all, not required for correct operation of your code. Provided you keep symbols that match your shipped binaries, you can still debug problems post mortem with all symbols loaded.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜