4

I am in debugger session with WinDbg. I type lm command and it shows loaded modules but I don't quite understand what does the (export symbols) mean below?

048c0000 0550c000   Db         (export symbols)       Db.dll
05520000 05535000   Graph      (export symbols)       Graph.dll

I was expecting it will either say symbols not loaded or loaded or deferred but it's none of that. What does the (export symbols) indicate in this case?

zar
  • 11,361
  • 14
  • 96
  • 178

1 Answers1

6

Exported symbols means that no PDB file was loaded and the symbols have been read from the binary (EXE, DLL) instead. A binary file has an export table. This table is used for resolving the symbols.

The export table is a feature of the PE file format. If you want to see it, you can use CFF Explorer. If you want a sample binary, use ntdll.dll from %windir%\system32:

Export table of NTDLL

Regarding the amount of information, it increases in this order:

  • no symbols
  • export symbols
  • public symbols
  • private symbols

You may also see "deferred" symbols, which means that WinDbg doesn't know yet, because it has not tried loading them. Use ld*;.reload if you want to get rid of the deferred symbols.

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
  • thanks, btw what is the different really between public and private other than private is my app and public is those available from microsoft? – zar Jun 29 '16 at 19:03
  • 1
    @zar: You might want to decide that you provide the symbols of your app to others for debugging purposes. So you send the PDB files to them. However, you don't want them to rely on private methods, private properties and private members. Therefore you remove those methods from the PDB file, before sending them to someone. You'll leave the public methods inside, because that typically defines an API. – Thomas Weller Jun 29 '16 at 19:06
  • 1
    @zar: so public symbols are not public because they are publically available, but because they only contain public methods etc. The tool to convert private symbols into public symbols is [PdbCopy](https://msdn.microsoft.com/en-us/library/ff560131(VS.85).aspx). Microsoft has once [removed too many symbols](http://stackoverflow.com/questions/32278634/is-there-a-known-issue-relating-to-windows-7-kernel-symbols/32278853#32278853) from NTDLL. – Thomas Weller Jun 29 '16 at 19:17
  • @ThomasWeller, can the `.NET Directory` in a PE file be regarded as export symbols? As far as I understand, information from this directory is used when debugging .NET application dumps. – UserName May 25 '21 at 18:24
  • @UserName: In .NET there's a lot of information in the IL code. You can get a lot of type information via reflection at runtime. This information is also accessible via the MsCorDac during debugging. I wouldn't compare it to exported symbols, though. – Thomas Weller May 25 '21 at 18:27
  • @ThomasWeller, the question arose from the thought: how does `WinDbg` know how .NET methods from the user code are called. According to this [link](https://www.wintellect.com/pdb-files-what-every-developer-must-know/) such information (for .NET) is stored directly in the `.exe`, `.dll`, or rather the mentioned directory at the level of the PE file - `All the other information is already in the .NET metadata so there is no need to duplicate the same information in a PDB file`. Then `DebuggableAttribute.DebuggingModes` comes into play, such as `IgnoreSymbolStoreSequencePoints`. – UserName May 25 '21 at 18:45
  • Probably the `MSIL offsets` mentioned during `JIT` execution are pointers to data from `.NET Directory` (more precisely, streams stored in it). And all this is somehow used by the debugger. But I'm not sure that this is correct, in any case, I did not find an official material with explanations. – UserName May 25 '21 at 18:48
  • @UserName: No expert on that, but my understanding is: the .NET DLL or EXE does not have a lot of methods in the classical sense, except maybe a few necessary like DllMain(). All the rest exists only as IL code. The .NET Runtime knows where to find the IL code in the DLL. The real methods are generated during JIT and the resulting methods may look different on x64 and x86. The .NET runtime and/or the DAC (data access control) keeps data structures that have the connection between IL code and compiled code. – Thomas Weller May 25 '21 at 22:07
  • @UserName: That's why you need a WinDbg extension (called SOS) which accesses these internal data structures and allows you to jump from native to IL or from IL to native. WinDbg alone is not capable of dealing with those structures, as they could change with each .NET release. The SOS extension comes with .NET, so you always have a version that matches your current .NET version. Debugging .NET without PDB files is quite simple. I've offered such services for some years. – Thomas Weller May 25 '21 at 22:14
  • This is definitely going too deep for me. Who could you ask? Steve Johnson (author of SOSEX, not very active recently), Konrad Kokosa (active on Twitter), Mario Hewardt (author of some books, haven't heard much of him recently), Hans Passant (also seems to be less active here on SO recently) – Thomas Weller May 25 '21 at 22:19