Is mismatched symbols complete show stopper or I can trust them partially to extract leads?

1

I don't have the correct symbol files (Pdbs) so I am using .reload /f /i to load what I have regenerated ignoring the time stamp. My project has many modules and this does load some of them but not others, I don't know why not all.

However I want to know how much can I trust the mismatch symbol file if anything at all. This the exception information from crash dump file

0:000> .exr -1
ExceptionAddress: 020b1143 (Db!CDbaAdoRecordset::CDbaAdoRecordset+0x00000073) [abc.cpp @80]
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 00000004
Attempt to read from address 00000004

Should I be reasonably sure that at least the crash is in the Db module? Can I also trust that the crash is in the same fil ename (abc.cpp) that it says it is? Is it more likely the call stack is correct when it shows the actual functions that I can actually see in code [including function names]?

I know the symbols and line numbers come from the pdb files so it's probably under question but what is it that the crash dump files contribute in all this connections which I can probably use to narrow down the problem?

I am trying to extract any leads or useful information that I can from mismatched symbol files.

Update

I am debugging the same version of code which produced the dump crash. Things like if modules, class names or file names could have been reamed can be completely ruled out since we don't do that. In theory the version I am debugging is exact match of the crashed version since its version controlled.

c++
windbg
asked on Stack Overflow Jul 13, 2016 by zar • edited Jul 14, 2016 by zar

2 Answers

3

I've had to do this same trick numerous times for releases that shipped without pdb files.

The closer your build environment is to the one used to build the binary, the better luck you'll have. Making sure you have the exact source code, compiler version, and compiler/linker flags used to build the binary will make your life a lot easier. Sometimes you'll get lucky and the symbols will be so close you won't even notice anything strange.

Should I be reasonably sure that at least the crash is in the Db module?

That is about the only thing you can be sure of. You actually have that information without symbols. (Without symbols, it tends to show an exported symbol with a big offset, like Db!DllMain+0x123456. In that case, you can still trust that the module is correct.)

Can I also trust that the crash is in the same filename (abc.cpp) that it says it is?

Nope. Your job is now to verify everything you see.

Things to verify:

  • When looking at the callstack, does the source code show the function calling the next frame somewhere in that function's body? If so, there's a good chance it is correct. If not, it still might be correct if a function call was inlined.

  • At the top frame, does the disassembly at the ExceptionAddress look like something that the compiler should have generated for the source code the symbols point to? (For example: I'd expect CDbaAdoRecordset's constructor to be calling methods related to RecordSets like CoCreateInstance(/*...*/, __uuidof(Recordset), /*...*/);.

The fact that you know what things come out of the symbol file (function names, line numbers, etc...) should give you an idea of what you're looking at and what might be wrong.


Your best bet is to start where you would normally start debugging even if you had matching symbols... Attempt to read from address 00000004 It's probably trying to access the offset 4 on an object that's null. What's that object? Godspeed!

answered on Stack Overflow Jul 14, 2016 by Sean Cline
3

Most things in an exception record are not related to PDBs, it will only be tried to resolve the exception address to a call stack.

I'm not exactly sure whether WinDbg would load a PDB for a DLL where the module name does not match. Also, it's unlikely you rename a DLL, I'd say.

So, things you can trust from an exception record with mismatched PDBs are:

ExceptionAddress: 020b1143 (Db!
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 00000004
Attempt to read from address 00000004

Things you can't trust:

!CDbaAdoRecordset::CDbaAdoRecordset+0x00000073) [abc.cpp @80]

Is it more likely the call stack is correct when it shows the actual functions that I can actually see in code [including function names]?

No. This may be accidental.

what is it that the crash dump files contribute in all this connections which I can probably use to narrow down the problem?

Nothing. You can only draw conclusions from your developer knowledge: what is the time difference of the mismatched PDB and the DLL and how many changes have you made in which files. Use a version control diff to find that out.

If you have made changes to the source code

This matching can go wrong, because

  • you have renamed the method in the meanwhile. Then the method name does not match
  • you have inserted lines, e.g. comments. Then the line number does not match
  • you have renamed the source file. Then the source file does not match.
  • you have added a class. This may change the address at which the compiler generates the method in question, because it has e.g. inserted the new class before.

If you have not made changes to the source code

This matching can still go wrong, because

  • your compiler environment has changed, e.g. due to an update or hotfix in the compiler, it now generates different assembly instructions.
  • you compile with different compiler settings (hopefully your compiler settings are stored along with the source code in a version control system, so you don't have this issue)
  • the compiler needn't compile the exact same way in another run. While there's no particular reason to compile it differently, compilers nowadays can compile in parallel (multi-threaded). Due to thread scheduling, some classes might be compiled in a different order, which may or may not result in a different DLL + PDB (depending on the implementation of the compiler or linker).
answered on Stack Overflow Jul 14, 2016 by Thomas Weller • edited Jul 15, 2016 by Thomas Weller

User contributions licensed under CC BY-SA 3.0