/////////////////////////////////////////////////////////////////////////////// // // SymLoad.cpp // // Author: Oleg Starodumov // // /////////////////////////////////////////////////////////////////////////////// // // Description: // // This example shows how to: // // * Initialize DbgHelp // * Load symbols for a module // * Check what kind of symbols is loaded // * Unload symbols for the module // * Deinitialize DbgHelp // // Actions: // // * Enable debug option // * Initialize DbgHelp // * Load symbols for the module // * Obtain and display information about loaded symbols // * Unload symbols for the module // * Deinitialize DbgHelp // // Command line parameters: // // * Path to the module you want to load symbols for // /////////////////////////////////////////////////////////////////////////////// // Include files // #include #include #include #include /////////////////////////////////////////////////////////////////////////////// // Directives // #pragma comment( lib, "dbghelp.lib" ) /////////////////////////////////////////////////////////////////////////////// // Declarations // void ShowSymbolInfo( DWORD64 ModBase ); /////////////////////////////////////////////////////////////////////////////// // main // int _tmain( int argc, const TCHAR* argv[] ) { BOOL bRet = FALSE; // Check command line parameters if( argc < 2 ) { _tprintf( _T("Usage: %s \n"), argv[0] ); return 0; } // Set options DWORD Options = SymGetOptions(); // SYMOPT_DEBUG option asks DbgHelp to print additional troubleshooting // messages to debug output - use the debugger's Debug Output window // to view the messages Options |= SYMOPT_DEBUG; ::SymSetOptions( Options ); // Initialize DbgHelp and load symbols for all modules of the current process bRet = ::SymInitialize ( GetCurrentProcess(), // Process handle of the current process NULL, // No user-defined search path -> use default FALSE // Do not load symbols for modules in the current process ); if( !bRet ) { _tprintf(_T("Error: SymInitialize() failed. Error code: %u \n"), ::GetLastError()); return 0; } // Load symbols for the module const TCHAR* pModName = argv[1]; _tprintf( _T("Loading symbols for module %s ... \n"), pModName ); DWORD64 ModBase = ::SymLoadModule64 ( GetCurrentProcess(), // Process handle of the current process NULL, // Handle to the module's image file (not needed) pModName, // Path/name of the module NULL, // User-defined short name of the module (it can be NULL) 0, // Base address of the module (can be NULL) 0 // Size of the module (can be NULL) ); if( ModBase == 0 ) { _tprintf(_T("Error: SymLoadModule64() failed. Error code: %u \n"), ::GetLastError()); return 0; } else { _tprintf( _T("Load address: %I64x \n"), ModBase ); // Obtain and display information about loaded symbols ShowSymbolInfo( ModBase ); // Unload symbols for the module bRet = ::SymUnloadModule64( GetCurrentProcess(), ModBase ); if( !bRet ) { _tprintf( _T("Error: SymUnloadModule64() failed. Error code: %u \n"), ::GetLastError() ); } } // Deinitialize DbgHelp bRet = ::SymCleanup( GetCurrentProcess() ); if( !bRet ) { _tprintf(_T("Error: SymCleanup() failed. Error code: %u \n"), ::GetLastError()); return 0; } // Complete return 0; } /////////////////////////////////////////////////////////////////////////////// // Functions // void ShowSymbolInfo( DWORD64 ModBase ) { // Get module information IMAGEHLP_MODULE64 ModuleInfo; memset(&ModuleInfo, 0, sizeof(ModuleInfo) ); ModuleInfo.SizeOfStruct = sizeof(ModuleInfo); BOOL bRet = ::SymGetModuleInfo64( GetCurrentProcess(), ModBase, &ModuleInfo ); if( !bRet ) { _tprintf(_T("Error: SymGetModuleInfo64() failed. Error code: %u \n"), ::GetLastError()); return; } // Display information about symbols // Kind of symbols switch( ModuleInfo.SymType ) { case SymNone: _tprintf( _T("No symbols available for the module.\n") ); break; case SymExport: _tprintf( _T("Loaded symbols: Exports\n") ); break; case SymCoff: _tprintf( _T("Loaded symbols: COFF\n") ); break; case SymCv: _tprintf( _T("Loaded symbols: CodeView\n") ); break; case SymSym: _tprintf( _T("Loaded symbols: SYM\n") ); break; case SymVirtual: _tprintf( _T("Loaded symbols: Virtual\n") ); break; case SymPdb: _tprintf( _T("Loaded symbols: PDB\n") ); break; case SymDia: _tprintf( _T("Loaded symbols: DIA\n") ); break; case SymDeferred: _tprintf( _T("Loaded symbols: Deferred\n") ); // not actually loaded break; default: _tprintf( _T("Loaded symbols: Unknown format.\n") ); break; } // Image name if( _tcslen( ModuleInfo.ImageName ) > 0 ) { _tprintf( _T("Image name: %s \n"), ModuleInfo.ImageName ); } // Loaded image name if( _tcslen( ModuleInfo.LoadedImageName ) > 0 ) { _tprintf( _T("Loaded image name: %s \n"), ModuleInfo.LoadedImageName ); } // Loaded PDB name if( _tcslen( ModuleInfo.LoadedPdbName ) > 0 ) { _tprintf( _T("PDB file name: %s \n"), ModuleInfo.LoadedPdbName ); } // Is debug information unmatched ? // (It can only happen if the debug information is contained // in a separate file (.DBG or .PDB) if( ModuleInfo.PdbUnmatched || ModuleInfo.DbgUnmatched ) { _tprintf( _T("Warning: Unmatched symbols. \n") ); } // Contents // Line numbers available ? _tprintf( _T("Line numbers: %s \n"), ModuleInfo.LineNumbers ? _T("Available") : _T("Not available") ); // Global symbols available ? _tprintf( _T("Global symbols: %s \n"), ModuleInfo.GlobalSymbols ? _T("Available") : _T("Not available") ); // Type information available ? _tprintf( _T("Type information: %s \n"), ModuleInfo.TypeInfo ? _T("Available") : _T("Not available") ); // Source indexing available ? _tprintf( _T("Source indexing: %s \n"), ModuleInfo.SourceIndexed ? _T("Yes") : _T("No") ); // Public symbols available ? _tprintf( _T("Public symbols: %s \n"), ModuleInfo.Publics ? _T("Available") : _T("Not available") ); }