我正在尝试从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下打印回溯?
答案 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/