I'm trying to call SymLoadModuleEx
to load the symbols from a PDB file and then use SymFromAddr
to look up symbols from that PDB. However, I can't figure out what to pass for the parameters BaseOfDll
and DllSize
-- the documentation explicitly says that when loading a PDB file, these parameters can't be 0, and indeed attempting to pass 0 results in it failing with ERROR_INVALID_PARAMETER
.
Here's what my code looks like:
SymSetOptions(SYMOPT_LOAD_LINES);
HANDLE hprocess = GetCurrentProcess();
if (!SymInitialize(hprocess, NULL, FALSE))
die("SymInitialize");
if(SymLoadModuleEx(hprocess, NULL, "full path to some PDB file.pdb", NULL,
0, // What to pass here?
0, // What to pass here?
NULL, 0) == 0)
{
die("SymLoadModuleEx");
}
How do you figure out what BaseOfDll
and DllSize
to pass in when loading a PDB file? The PDB file in question is the symbol file for a different program executable (not a DLL), and just for the sake of argument, assume that you don't have access to the original EXE from which the PDB was generated.
Alternatively, is there a better method of looking up the symbols corresponding to a given address from a PDB file?
dbghelp.dll and the
Sym*
methods here make use of the Debug Interface Access (DIA) SDK.1DIA itself is COM-based and much more flexible than what DbgHelp offers.
Specifically, to load a known PDB and lookup a symbol based on an address, you can do the following:
IDiaDataSource::loadDataFromPdb
to load a specific PDB (DLL size and base address are not needed).IDiaDataSource::openSession
to get theIDiaSession
for your data source.findSymbolByVA
orfindSymbolByRVA
, respectively, to get theIDiaSymbol
associated with that address.IDiaSymbol::get_name
to get the function name containing the address you specified.None of this requires the original image; only the PDB is required. Assuming you're using Visual Studio, the headers and libraries for DIA are available under (for example):
C:\Program Files (x86)\Microsoft Visual Studio 10.0\DIA SDK
.