sBool PDBFileReader::ReadDebugInfo(sChar *fileName,DebugInfo &to) { sBool readOk = sFALSE; if(FAILED(CoInitialize(0))) return sFALSE; IDiaDataSource *source = 0; CoCreateInstance(__uuidof(DiaSource),0,CLSCTX_INPROC_SERVER, __uuidof(IDiaDataSource),(void**) &source); if(source) { wchar_t wideFileName[260]; mbstowcs(wideFileName,fileName,260); if(SUCCEEDED(source->loadDataForExe(wideFileName,0,0))) { if(SUCCEEDED(source->openSession(&Session))) { ReadEverything(to); readOk = sTRUE; Session->Release(); } } source->Release(); } CoUninitialize(); return readOk; }
static void ProcessPdbFile(const char *fileNameA) { HRESULT hr; IDiaDataSource * dia = NULL; IDiaSession * session = NULL; str::Str<char> report; dia = LoadDia(); if (!dia) return; ScopedMem<WCHAR> fileName(str::conv::FromAnsi(fileNameA)); hr = dia->loadDataForExe(fileName, 0, 0); if (FAILED(hr)) { logf(" failed to load %s or its debug symbols from .pdb file\n", fileNameA); goto Exit; } hr = dia->openSession(&session); if (FAILED(hr)) { log(" failed to open DIA session\n"); goto Exit; } if (g_dumpTypes) DumpTypes(session); if (g_dumpSections) DumpSections(session); if (g_dumpSymbols) DumpSymbols(session); fputs("Format: 1\n", stdout); if (g_compact) { str::Str<char> res; GetInternedStringsReport(res); fputs(res.Get(), stdout); } fputs(g_report.Get(), stdout); Exit: UnkReleaseSafe(session); }
HRESULT open( const char *input_file, const char *user_spath = NULL, ea_t load_address = BADADDR, input_exe_reader_t exe_reader = NULL, input_mem_reader_t mem_reader = NULL) { // Already open? if ( pSession != NULL ) return S_OK; // When the debugger is active, first try to load debug directory from the memory ea_t load_address_order[2]; // when remote debugging, don't use files on disk bool remote_debug = false; #ifndef BUILDING_EFD #ifndef PDBTOTIL if ( get_process_state() != DSTATE_NOTASK ) { load_address_order[0] = load_address; load_address_order[1] = BADADDR; remote_debug = dbg->is_remote(); } else #endif #endif { load_address_order[0] = BADADDR; load_address_order[1] = load_address; } HRESULT hr; do { // No interface was created? hr = create_dia_source(); if ( FAILED(hr) ) break; qwstring wpath, winput; get_input_and_sym_path(input_file, user_spath, winput, wpath); if ( exe_reader == NULL && mem_reader == NULL && !remote_debug ) // Try to load input file as PDB hr = pSource->loadDataFromPdb(winput.c_str()); else hr = E_FAIL; // Failed? Try to load as EXE if ( FAILED(hr) ) { CCallback callback(exe_reader, mem_reader); callback.AddRef(); if ( !remote_debug ) { // Open the executable callback.OpenExe(winput.c_str()); } for ( int i=0; i < qnumber(load_address_order); i++ ) { callback.SetLoadAddress(load_address_order[i]); hr = pSource->loadDataForExe(winput.c_str(), wpath.c_str(), (IDiaLoadCallback *)&callback); if ( SUCCEEDED(hr) ) break; } } // Failed? Then nothing else to try, quit if ( FAILED(hr) ) break; // Open a session for querying symbols hr = pSource->openSession(&pSession); if ( FAILED(hr) ) break; // Set load address if ( load_address != BADADDR ) pSession->put_loadAddress(load_address); // Retrieve a reference to the global scope hr = pSession->get_globalScope(&pGlobal); if ( FAILED(hr) ) break; hr = S_OK; } while ( false ); // Make sure we cleanup if ( FAILED(hr) ) close(); return hr; }
sBool PDBFileReader::ReadDebugInfo(sChar *fileName,DebugInfo &to) { static const struct DLLDesc { const char *Filename; IID UseCLSID; } DLLs[] = { "msdia71.dll", __uuidof(DiaSource71), "msdia80.dll", __uuidof(DiaSource80), "msdia90.dll", __uuidof(DiaSource90), // add more here as new versions appear (as long as they're backwards-compatible) 0 }; sBool readOk = false; if(FAILED(CoInitialize(0))) { fprintf(stderr, " failed to initialize COM\n"); return false; } IDiaDataSource *source = 0; HRESULT hr = E_FAIL; // Try creating things "the official way" for(sInt i=0;DLLs[i].Filename;i++) { hr = CoCreateInstance(DLLs[i].UseCLSID,0,CLSCTX_INPROC_SERVER, __uuidof(IDiaDataSource),(void**) &source); if(SUCCEEDED(hr)) break; } if(FAILED(hr)) { // None of the classes are registered, but most programmers will have the // DLLs on their system anyway and can copy it over; try loading it directly. for(sInt i=0;DLLs[i].Filename;i++) { HMODULE hDIADll = LoadLibrary(DLLs[i].Filename); if(hDIADll) { typedef HRESULT (__stdcall *PDllGetClassObject)(REFCLSID rclsid,REFIID riid,void** ppvObj); PDllGetClassObject DllGetClassObject = (PDllGetClassObject) GetProcAddress(hDIADll,"DllGetClassObject"); if(DllGetClassObject) { // first create a class factory IClassFactory *classFactory; hr = DllGetClassObject(DLLs[i].UseCLSID,IID_IClassFactory,(void**) &classFactory); if(SUCCEEDED(hr)) { hr = classFactory->CreateInstance(0,__uuidof(IDiaDataSource),(void**) &source); classFactory->Release(); } } if(SUCCEEDED(hr)) break; else FreeLibrary(hDIADll); } } } if(source) { wchar_t wideFileName[260]; mbstowcs(wideFileName,fileName,260); if(SUCCEEDED(source->loadDataForExe(wideFileName,0,0))) { if(SUCCEEDED(source->openSession(&Session))) { ReadEverything(to); readOk = true; Session->Release(); } else fprintf(stderr," failed to open DIA session\n"); } else fprintf(stderr," failed to load debug symbols (PDB not found)\n"); source->Release(); } else fprintf(stderr," couldn't find (or properly initialize) any DIA dll, copying msdia*.dll to app dir might help.\n"); CoUninitialize(); return readOk; }