Win32 - 从C代码回溯

Mac*_*ade 43 c windows backtrace

我目前正在寻找一种在Windows下从C代码(无C++)获取回溯信息的方法.

我正在构建一个跨平台的C库,带有引用计数内存管理.它还有一个集成的内存调试器,提供有关内存错误的信息(XEOS C Foundation Library).

发生故障时,将启动调试器,提供有关故障的信息以及所涉及的内存记录.

在此输入图像描述

在Linux或Mac OS X上,我可以查找execinfo.h以便使用该backtrace功能,因此我可以显示有关内存故障的其他信息.

我在Windows上寻找同样的东西.

我已经看过如何在C中获取堆栈跟踪?在Stack Overflow上.我不想使用第三方库,所以CaptureStackBackTrace或者StackWalk函数看起来不错.

唯一的问题是我只是不知道如何使用它们,即使使用Microsoft文档.

我不习惯Windows编程,因为我通常在兼容POSIX的系统上工作.

对这些功能有什么解释,也许是一些例子?

编辑

我现在正在考虑使用这个CaptureStackBackTrace函数DbgHelp.lib,因为似乎开销有点少......

这是我到目前为止所尝试的:

unsigned int   i;
void         * stack[ 100 ];
unsigned short frames;
SYMBOL_INFO    symbol;
HANDLE         process;

process = GetCurrentProcess();

SymInitialize( process, NULL, TRUE );

frames = CaptureStackBackTrace( 0, 100, stack, NULL );

for( i = 0; i < frames; i++ )
{
    SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, &symbol );

    printf( "%s\n", symbol.Name );
}
Run Code Online (Sandbox Code Playgroud)

我刚搞砸了.我想我应该使用别的东西SymFromAddr.

Mac*_*ade 47

好吧,现在我明白了.:)

问题出在SYMBOL_INFO结构中.它需要在堆上分配,为符号名称保留空间,并正确初始化.

这是最终的代码:

void printStack( void );
void printStack( void )
{
     unsigned int   i;
     void         * stack[ 100 ];
     unsigned short frames;
     SYMBOL_INFO  * symbol;
     HANDLE         process;

     process = GetCurrentProcess();

     SymInitialize( process, NULL, TRUE );

     frames               = CaptureStackBackTrace( 0, 100, stack, NULL );
     symbol               = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
     symbol->MaxNameLen   = 255;
     symbol->SizeOfStruct = sizeof( SYMBOL_INFO );

     for( i = 0; i < frames; i++ )
     {
         SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );

         printf( "%i: %s - 0x%0X\n", frames - i - 1, symbol->Name, symbol->Address );
     }

     free( symbol );
}
Run Code Online (Sandbox Code Playgroud)

输出是:

6: printStack - 0xD2430
5: wmain - 0xD28F0
4: __tmainCRTStartup - 0xE5010
3: wmainCRTStartup - 0xE4FF0
2: BaseThreadInitThunk - 0x75BE3665
1: RtlInitializeExceptionChain - 0x770F9D0F
0: RtlInitializeExceptionChain - 0x770F9D0F
Run Code Online (Sandbox Code Playgroud)

  • 没有什么要求`SYMBOL_INFO`结构在堆上.它在堆栈上运行得很好. (2认同)