Win32 - 来自cygwin下的C代码的Backtrace

时间:2016-05-05 13:11:45

标签: c debugging cygwin backtrace

我正在尝试从cg代码编译回溯,这是在cygwin下编译的。 我从这里得到了第一个答案: Win32 - Backtrace from C code

我在cygwin shell下写过:

User@WIN-EO6FNSIC9C1 ~
$ cat test.c
#include <windows.h>
#include <dbghelp.h>
#include <assert.h>
#include <stdio.h>
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, 50, 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 );
}


int foo2() {
        printStack();
}
void foo() {
        foo2();
}
int main() {
foo();
}

User@WIN-EO6FNSIC9C1 ~
$ gcc test.c -ldbghelp -g
test.c: In function ‘printStack’:
test.c:22:32: warning: cast from pointer to integer of different size    [-Wpointer-to-int-cast]
      SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );
                                ^

User@WIN-EO6FNSIC9C1 ~
$ ./a.exe
4:  - 0x0
3:  - 0x0
2:  - 0x0
1:  - 0x0
0: cygwin_dll_init - 0x61006C30

为什么打印空行和零地址?是否可以使用CaptureStackBackTrace或类似的东西在cygwin下打印回溯?

1 个答案:

答案 0 :(得分:2)

这是一个解决方案

$ cat test.c
#include <windows.h>
#include <dbghelp.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <imagehlp.h>
#define BACKTRACE_BT_BUFFER_SIZE 61

char * PROGRAM_NAME = NULL;
/* Resolve symbol name and source location given the path to the executable
   and an address */
int addr2line(char const * const program_name, void const * const addr)
{
  char addr2line_cmd[512] = {0};
  sprintf(addr2line_cmd,"addr2line -f -p -e %.256s %p", program_name, addr);
  /* This will print a nicely formatted string specifying the
     function and source line of the address */
  return system(addr2line_cmd);
}

void printStack()
{
     assert(PROGRAM_NAME != NULL);
     unsigned int   i;
     void         * stack[ BACKTRACE_BT_BUFFER_SIZE ];
     unsigned short frames;
     SYMBOL_INFO  * symbol;
     HANDLE         process;

     process = GetCurrentProcess();
     SymInitialize( process, NULL, TRUE );
     frames               = CaptureStackBackTrace( 0, BACKTRACE_BT_BUFFER_SIZE, stack, NULL );
     for( i = 0; i < frames; i++ )
     {
         addr2line(PROGRAM_NAME, stack[i]);
     }
}


int foo2() {
printStack();
}
void foo() {
        foo2();
}

int main(int argc, char*argv[]) {
        PROGRAM_NAME = argv[0];
        foo();
}

User@WIN-EO6FNSIC9C1 ~
$ gcc test.c -ldbghelp -g

User@WIN-EO6FNSIC9C1 ~
$ ./a.exe
printStack у /home/User/test.c:32
foo2 у /home/User/test.c:42
foo у /home/User/test.c:45
main у /home/User/test.c:49
?? ??:0

看起来无法在.exe文件中使用SymInitialize。 https://www.cygwin.com/ml/cygwin-developers/2015-03/msg00006.html

感谢https://spin.atomicobject.com/2013/01/13/exceptions-stack-traces-c/