StackWalk64 sur Windows - Get nom de symbole

Bien, deuxième question, DONC, en une seule journée. Ressemble à de la programmation sous Windows me rend heureux... : S

Je suis en train d'essayer d'obtenir la pile d'appels de fonction sur un exécutable Win32.

Ce matin, j'ai aussi posé une question à ce sujet:

Win32 - Backtrace de code C

Maintenant, je suis sûr que les StackWalk64 la fonction est la clé pour cela.
J'ai lu quelques articles sur la façon de l'utiliser, ainsi que le MS documentation.

Il réellement affiche les images sur mon programme de test, donc un peu de travail...

Le problème est que je ne suis pas en mesure de récupérer le nom du symbole de la pile informations.

Je suis en utilisant le SymGetSymFromAddr64 la fonction de ce, avec UnDecorateSymbolName. Mais je ne reçois que des caractères indésirables.

Voici mon code. Espérons que c'est de ne pas le désordre, comme je n'ai pas l'habitude de la programmation sous Windows:

void printStack( void )
{
BOOL                result;
HANDLE              process;
HANDLE              thread;
CONTEXT             context;
STACKFRAME64        stack;
ULONG               frame;
IMAGEHLP_SYMBOL64   symbol;
DWORD64             displacement;
char name[ 256 ];
RtlCaptureContext( &context );
memset( &stack, 0, sizeof( STACKFRAME64 ) );
process                = GetCurrentProcess();
thread                 = GetCurrentThread();
displacement           = 0;
stack.AddrPC.Offset    = context.Eip;
stack.AddrPC.Mode      = AddrModeFlat;
stack.AddrStack.Offset = context.Esp;
stack.AddrStack.Mode   = AddrModeFlat;
stack.AddrFrame.Offset = context.Ebp;
stack.AddrFrame.Mode   = AddrModeFlat;
for( frame = 0; ; frame++ )
{
result = StackWalk64
(
IMAGE_FILE_MACHINE_I386,
process,
thread,
&stack,
&context,
NULL,
SymFunctionTableAccess64,
SymGetModuleBase64,
NULL
);
symbol.SizeOfStruct  = sizeof( IMAGEHLP_SYMBOL64 );
symbol.MaxNameLength = 255;
SymGetSymFromAddr64( process, ( ULONG64 )stack.AddrPC.Offset, &displacement, &symbol );
UnDecorateSymbolName( symbol.Name, ( PSTR )name, 256, UNDNAME_COMPLETE );
printf
(
"Frame %lu:\n"
"    Symbol name:    %s\n"
"    PC address:     0x%08LX\n"
"    Stack address:  0x%08LX\n"
"    Frame address:  0x%08LX\n"
"\n",
frame,
symbol.Name,
( ULONG64 )stack.AddrPC.Offset,
( ULONG64 )stack.AddrStack.Offset,
( ULONG64 )stack.AddrFrame.Offset
);
if( !result )
{
break;
}
}
}

La production réelle est:

Frame 0:
Symbol name:    ╠╠╠╠╠╠╠╠╠╠╠╠
PC address:     0x00BA2763
Stack address:  0x00000000
Frame address:  0x0031F7E8
Frame 1:
Symbol name:    ╠╠╠╠╠╠╠╠╠╠╠╠☺
PC address:     0x00BB4FFF
Stack address:  0x00000000
Frame address:  0x0031F940
Frame 2:
Symbol name:    ╠╠╠╠╠╠╠╠╠╠╠╠☻
PC address:     0x00BB4E2F
Stack address:  0x00000000
Frame address:  0x0031F990
Frame 3:
Symbol name:    ╠╠╠╠╠╠╠╠╠╠╠╠♥
PC address:     0x75BE3677
Stack address:  0x00000000
Frame address:  0x0031F998
Frame 4:
Symbol name:    ╠╠╠╠╠╠╠╠╠╠╠╠♦
PC address:     0x770F9D72
Stack address:  0x00000000
Frame address:  0x0031F9A4
Frame 5:
Symbol name:    ╠╠╠╠╠╠╠╠╠╠╠╠♣
PC address:     0x770F9D45
Stack address:  0x00000000
Frame address:  0x0031F9E4
Frame 6:
Symbol name:    ╠╠╠╠╠╠╠╠╠╠╠╠♠
PC address:     0x770F9D45
Stack address:  0x00000000
Frame address:  0x0031F9E4

Semble bizarre que la pile l'adresse est toujours à 0 par le chemin... Toute aide appréciée : )

Merci à tout le monde!

MODIFIER

Je suis à la recherche d'un simple C de la solution, sans tiers des bibliothèques...

Avez-vous vérifié les codes de retour de SymGetSymFromAddr64 et UnDecorateSymbolName?
vous devez appeler SymInitialize, comme mentionné par Muqker

OriginalL'auteur Macmade | 2011-04-18