Пытаюсь работать с DbgHelp функциями. Запускаю под XP SP3 32 следующую программку и получаю на выходе
StackRebuilder.exe Test.exe
Loading symbols for module Test.exe ...
Load address: 400000
Error: SymGetModuleInfo64() failed. Error code: 87
Насколько я понял после link removed, проблема в том, что DbgHelp.dll , даже положенная в папку с выполняемым файлом не всегда им используется. Но я так и не понял, что надо сделать, чтобы заставить использоваться эту локальную dll.
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"StackRebuilder.cpp"</div></div><div class="sp-body"><div class="sp-content">// StackRebuilder.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
///////////////////////////////////////////////////////////////////////////////
// Include files
//
#include <windows.h>
#include <tchar.h>
#include <dbghelp.h>
#include <stdio.h>
///////////////////////////////////////////////////////////////////////////////
// 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 <ModulePathAndName> \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 = ::SymLoadModuleEx (
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)
0, // A pointer to a MODLOAD_DATA structure that represents headers other than the standard PE header. This parameter is optional and can be NULL.
0 //If this parameter is zero, the function loads the modules and the symbols for the module.
);
if( ModBase == 0 )
{
_tprintf(_T("Error: SymLoadModuleEx() 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: SymUnloadModule() 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") );
}
StackRebuilder.exe Test.exe
Loading symbols for module Test.exe ...
Load address: 400000
Error: SymGetModuleInfo64() failed. Error code: 87
Насколько я понял после
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"StackRebuilder.cpp"</div></div><div class="sp-body"><div class="sp-content">// StackRebuilder.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
///////////////////////////////////////////////////////////////////////////////
// Include files
//
#include <windows.h>
#include <tchar.h>
#include <dbghelp.h>
#include <stdio.h>
///////////////////////////////////////////////////////////////////////////////
// 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 <ModulePathAndName> \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 = ::SymLoadModuleEx (
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)
0, // A pointer to a MODLOAD_DATA structure that represents headers other than the standard PE header. This parameter is optional and can be NULL.
0 //If this parameter is zero, the function loads the modules and the symbols for the module.
);
if( ModBase == 0 )
{
_tprintf(_T("Error: SymLoadModuleEx() 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: SymUnloadModule() 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") );
}