3

I know StackWalk64() API can be used to print call stack in windows. There has been quite a few discussions about how does this work on SO.

Function Call Stack in C++

StackWalk64 on Windows - Get symbol name

StackWalker - Walking the callstack

I observed StackWalk64() requires symbol file(PDB file) to present in order to find out function names. If pdb file is not present symbol info is not printed.

My questions are -

  1. Is my understanding correct ? I don't find this documented.
  2. Is this API exposed for testing/debugging purpose ? How to make it work on
    production systems where pdb files are not present ?
  3. On Linux if symbol file is not present then mangled like call stack printed. At least can it be achieved on windows ?
Community
  • 1
  • 1
irsis
  • 952
  • 1
  • 13
  • 33
  • C++ compilers optimize too aggressively to permit reliable stack walking. Even if you tell your compiler to not omit stack frames then it will still do so in leaf functions. Providing a PDB is of course never a real problem, there is very little point in making it one. – Hans Passant Feb 18 '15 at 12:47
  • @HansPassant Imagine a situation when you have a huge product which ships hundreds of dlls. Providing PDBs all the time will require lot of changes e.g. build process, packaging, storage etc. – irsis Feb 18 '15 at 12:54
  • 1
    On production systems you do not dump stack traces. When your application fails you write a dump file to disk (using [MiniDumpWriteDump](https://msdn.microsoft.com/en-us/library/windows/desktop/ms680360.aspx)). This dump file can be opened in a debugger. Together with symbol information from the .pdb files this produces stack traces (amongst other things). The .pdb files do not need to be deployed to generate a dump file. – IInspectable Feb 18 '15 at 12:55
  • 1
    This, of course, implies that you generate .pdb files for your release configurations, and place them under source control. – IInspectable Feb 18 '15 at 12:57
  • @ IInspectable This is true most of the time. But imagine a case when we intentionally wants to print a stack trace whenever any exception/error situation arise. That's what is happening in our product. It has been working fine on non-windows platforms I need to get it work on windows. That's why I asked this question. – irsis Feb 18 '15 at 12:59
  • Why do you want to print a stack trace (that's of really limited use) instead of creating a useful mini dump? – IInspectable Feb 18 '15 at 13:00
  • @IInspectable Well, mini dump is helpful when application is crashed. We print call stack on exceptional situation and when the trace level is high. I hope you see the context now. – irsis Feb 18 '15 at 13:02
  • And what keeps you from writing a mini dump instead? If required you can get a mini dump so small, that it's hardly any larger than the callstack string representation. – IInspectable Feb 18 '15 at 13:47
  • @IInspectable Please try to understand I can write a mini dump but it is not the requirement here. – irsis Feb 18 '15 at 14:13

2 Answers2

2

If it's just a stack trace, CaptureStackBackTrace() should be enough for you.

void *stack[48];
USHORT count = CaptureStackBackTrace(0, 48, stack, NULL);
for(USHORT c = 0; c < count; c++)
  printf("addr %02d: %p\n", c, stack[c]);
ssbssa
  • 1,261
  • 1
  • 13
  • 21
  • 1
    I already had tried `CaptureStackBackTrace() ` but result was the same. It will print the addr but not the method names in the absence of PDB file. – irsis Feb 20 '15 at 09:28
  • Then I guess I misunderstood the question. For method names you obviously need the PDB file. – ssbssa Feb 20 '15 at 12:38
  • Hmm... @Rahul, are you building this with MinGW or one of its variants, by any chance? Those don't use PDB files but rather embed DWARF debugging information directly into your executable, and I don't think Microsoft's debugging functions can read that... at least not on their own...??? Your original post mentioned Linux and that's definitely the case on Linux (DWARF data embedded in the binary, though external symbol files can be used as well... they're not PDB-format files though). – andlabs Feb 21 '15 at 09:47
  • @Rahul would http://www.mr-edd.co.uk/code/dbg help? it's a stack tracing library that would support MinGW (since you didn't answer the above question) and was found by googling "capturestackbacktrace mingw"; I'm still not sure if it's that `CaptureStackBackTrace()` doesn't support the DWARF debug symbols that it produces or not... It does support MSVC as well but I think you'l stil need a PDB file because its linker won't generate anything else (I need to ask about embedding C 7.0/COFF symbols myself...) – andlabs Feb 26 '15 at 20:40
  • @andlabs Thank you for answer. No, I am not building this with MinGW. The code that I've works on Couple of Linux platforms and on windows. Symbols might be printed on Linux because it uses DWARF format but true may be COFF format always requires PDF files. So in short conclusion is that on windows (COFF format) we always need pdf files to print symbols unlike on Linux (DWARF format) ? – irsis Feb 27 '15 at 07:14
  • 1
    No, the format isn't the reason. The way the symbols are stored is the reason. It's apparent that the Windows debugging functions you're calling expect *a separate PDB file* because that's how Microsoft stores debugging information. And on Linux, debugging information is often stored as DWARF-format data *in the executable*. You could probably ask (separately) if there's a way to get Microsoft's tools to link your program to store debugging information directly in the executable instead of in a PDB file, but I don't know offhand. (`/Z7` to compiler seems to store directly in object files.) – andlabs Feb 27 '15 at 09:03
0

Answers to your questions -

1. Is my understanding correct ? I don't find this documented.

Yes. You need symbols to print function names. No need to have private symbols, public symbols will also work (if you want to ship pdbs).

2. Is this API exposed for testing/debugging purpose ? How to make it work on production systems where pdb files are not present ?

This API is mainly for debuggers but it can be used in many tools e.g. Advance task manager which shows thread stack (ProcessExplorer). If you want function names then symbols are required (at least public symbols).

3. On Linux if symbol file is not present then mangled like call stack printed. At least can it be achieved on windows

What you can achieve without symbols is - call stack will modulename with offset (from start of module) e.g. xyz.dll+0x62

sunilnmu
  • 151
  • 2