Symgetmoduleinfo64 Возвращает Error Code: 87

puks

Well-Known Member
Lotus team
03.02.2007
1 971
16
#1
Пытаюсь работать с DbgHelp функциями. Запускаю под XP SP3 32 следующую программку и получаю на выходе

StackRebuilder.exe Test.exe
Loading symbols for module Test.exe ...
Load address: 400000
Error: SymGetModuleInfo64() failed. Error code: 87

Насколько я понял после
Чтобы видеть этот контент необходимо: Войти или зарегистрироваться
, проблема в том, что 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") );

}