C++ Windows下的异常处理和堆栈跟踪(MinGW/gcc)
我需要使Linux/GCC异常处理系统与Windows/MinGW兼容 注意:我需要从共享库中捕获并回溯异常 下面是我如何在Linux/GCC下实现它的 标题:C++ Windows下的异常处理和堆栈跟踪(MinGW/gcc),c++,windows,mingw,shared-libraries,stack-trace,C++,Windows,Mingw,Shared Libraries,Stack Trace,我需要使Linux/GCC异常处理系统与Windows/MinGW兼容 注意:我需要从共享库中捕获并回溯异常 下面是我如何在Linux/GCC下实现它的 标题: #include <execinfo.h> #include <signal.h> static void handler(int sig) { // Catch exceptions switch(sig) { case SIGABRT: fputs("Caught SIGAB
#include <execinfo.h>
#include <signal.h>
static void handler(int sig)
{
// Catch exceptions
switch(sig)
{
case SIGABRT:
fputs("Caught SIGABRT: usually caused by an abort() or assert()\n", stderr);
break;
case SIGFPE:
fputs("Caught SIGFPE: arithmetic exception, such as divide by zero\n",
stderr);
break;
case SIGILL:
fputs("Caught SIGILL: illegal instruction\n", stderr);
break;
case SIGINT:
fputs("Caught SIGINT: interactive attention signal, probably a ctrl+c\n",
stderr);
break;
case SIGSEGV:
fputs("Caught SIGSEGV: segfault\n", stderr);
break;
case SIGTERM:
default:
fputs("Caught SIGTERM: a termination request was sent to the program\n",
stderr);
break;
}
// Print stacktrace
void *array[10];
size_t size;
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// Ctrl+C interrupt => No backtrace
if (sig != (int)SIGINT) {
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, 2);
}
exit(sig);
}
signal(SIGABRT, handler);
signal(SIGFPE, handler);
signal(SIGILL, handler);
signal(SIGINT, handler);
signal(SIGSEGV, handler);
signal(SIGTERM, handler);
#include <windows.h>
static LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS * ExceptionInfo)
{
switch(ExceptionInfo->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
fputs("Error: EXCEPTION_ACCESS_VIOLATION\n", stderr);
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
fputs("Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED\n", stderr);
break;
case EXCEPTION_BREAKPOINT:
fputs("Error: EXCEPTION_BREAKPOINT\n", stderr);
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
fputs("Error: EXCEPTION_DATATYPE_MISALIGNMENT\n", stderr);
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
fputs("Error: EXCEPTION_FLT_DENORMAL_OPERAND\n", stderr);
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
fputs("Error: EXCEPTION_FLT_DIVIDE_BY_ZERO\n", stderr);
break;
case EXCEPTION_FLT_INEXACT_RESULT:
fputs("Error: EXCEPTION_FLT_INEXACT_RESULT\n", stderr);
break;
case EXCEPTION_FLT_INVALID_OPERATION:
fputs("Error: EXCEPTION_FLT_INVALID_OPERATION\n", stderr);
break;
case EXCEPTION_FLT_OVERFLOW:
fputs("Error: EXCEPTION_FLT_OVERFLOW\n", stderr);
break;
case EXCEPTION_FLT_STACK_CHECK:
fputs("Error: EXCEPTION_FLT_STACK_CHECK\n", stderr);
break;
case EXCEPTION_FLT_UNDERFLOW:
fputs("Error: EXCEPTION_FLT_UNDERFLOW\n", stderr);
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
fputs("Error: EXCEPTION_ILLEGAL_INSTRUCTION\n", stderr);
break;
case EXCEPTION_IN_PAGE_ERROR:
fputs("Error: EXCEPTION_IN_PAGE_ERROR\n", stderr);
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
fputs("Error: EXCEPTION_INT_DIVIDE_BY_ZERO\n", stderr);
break;
case EXCEPTION_INT_OVERFLOW:
fputs("Error: EXCEPTION_INT_OVERFLOW\n", stderr);
break;
case EXCEPTION_INVALID_DISPOSITION:
fputs("Error: EXCEPTION_INVALID_DISPOSITION\n", stderr);
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
fputs("Error: EXCEPTION_NONCONTINUABLE_EXCEPTION\n", stderr);
break;
case EXCEPTION_PRIV_INSTRUCTION:
fputs("Error: EXCEPTION_PRIV_INSTRUCTION\n", stderr);
break;
case EXCEPTION_SINGLE_STEP:
fputs("Error: EXCEPTION_SINGLE_STEP\n", stderr);
break;
case EXCEPTION_STACK_OVERFLOW:
fputs("Error: EXCEPTION_STACK_OVERFLOW\n", stderr);
break;
default:
fputs("Error: Unrecognized Exception\n", stderr);
break;
}
fflush(stderr);
if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
{
// TODO : ...
//windows_print_stacktrace(ExceptionInfo->ContextRecord);
}
return EXCEPTION_EXECUTE_HANDLER;
}
#include <windows.h>
#include <imagehlp.h>
void windows_print_stacktrace(CONTEXT* context)
{
SymInitialize(GetCurrentProcess(), 0, true);
STACKFRAME frame = { 0 };
/* setup initial stack frame */
frame.AddrPC.Offset = context->Eip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrStack.Offset = context->Esp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context->Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
while (StackWalk(IMAGE_FILE_MACHINE_I386 ,
GetCurrentProcess(),
GetCurrentThread(),
&frame,
context,
0,
SymFunctionTableAccess,
SymGetModuleBase,
0 ) )
{
addr2line(global_program_name, (void*)frame.AddrPC.Offset);
}
SymCleanup( GetCurrentProcess() );
}
所有这些在Linux下都可以正常工作。
现在我希望在我的库的Windows版本下有相同的行为
以下是我捕获异常的方法:
#include <execinfo.h>
#include <signal.h>
static void handler(int sig)
{
// Catch exceptions
switch(sig)
{
case SIGABRT:
fputs("Caught SIGABRT: usually caused by an abort() or assert()\n", stderr);
break;
case SIGFPE:
fputs("Caught SIGFPE: arithmetic exception, such as divide by zero\n",
stderr);
break;
case SIGILL:
fputs("Caught SIGILL: illegal instruction\n", stderr);
break;
case SIGINT:
fputs("Caught SIGINT: interactive attention signal, probably a ctrl+c\n",
stderr);
break;
case SIGSEGV:
fputs("Caught SIGSEGV: segfault\n", stderr);
break;
case SIGTERM:
default:
fputs("Caught SIGTERM: a termination request was sent to the program\n",
stderr);
break;
}
// Print stacktrace
void *array[10];
size_t size;
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// Ctrl+C interrupt => No backtrace
if (sig != (int)SIGINT) {
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, 2);
}
exit(sig);
}
signal(SIGABRT, handler);
signal(SIGFPE, handler);
signal(SIGILL, handler);
signal(SIGINT, handler);
signal(SIGSEGV, handler);
signal(SIGTERM, handler);
#include <windows.h>
static LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS * ExceptionInfo)
{
switch(ExceptionInfo->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
fputs("Error: EXCEPTION_ACCESS_VIOLATION\n", stderr);
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
fputs("Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED\n", stderr);
break;
case EXCEPTION_BREAKPOINT:
fputs("Error: EXCEPTION_BREAKPOINT\n", stderr);
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
fputs("Error: EXCEPTION_DATATYPE_MISALIGNMENT\n", stderr);
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
fputs("Error: EXCEPTION_FLT_DENORMAL_OPERAND\n", stderr);
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
fputs("Error: EXCEPTION_FLT_DIVIDE_BY_ZERO\n", stderr);
break;
case EXCEPTION_FLT_INEXACT_RESULT:
fputs("Error: EXCEPTION_FLT_INEXACT_RESULT\n", stderr);
break;
case EXCEPTION_FLT_INVALID_OPERATION:
fputs("Error: EXCEPTION_FLT_INVALID_OPERATION\n", stderr);
break;
case EXCEPTION_FLT_OVERFLOW:
fputs("Error: EXCEPTION_FLT_OVERFLOW\n", stderr);
break;
case EXCEPTION_FLT_STACK_CHECK:
fputs("Error: EXCEPTION_FLT_STACK_CHECK\n", stderr);
break;
case EXCEPTION_FLT_UNDERFLOW:
fputs("Error: EXCEPTION_FLT_UNDERFLOW\n", stderr);
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
fputs("Error: EXCEPTION_ILLEGAL_INSTRUCTION\n", stderr);
break;
case EXCEPTION_IN_PAGE_ERROR:
fputs("Error: EXCEPTION_IN_PAGE_ERROR\n", stderr);
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
fputs("Error: EXCEPTION_INT_DIVIDE_BY_ZERO\n", stderr);
break;
case EXCEPTION_INT_OVERFLOW:
fputs("Error: EXCEPTION_INT_OVERFLOW\n", stderr);
break;
case EXCEPTION_INVALID_DISPOSITION:
fputs("Error: EXCEPTION_INVALID_DISPOSITION\n", stderr);
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
fputs("Error: EXCEPTION_NONCONTINUABLE_EXCEPTION\n", stderr);
break;
case EXCEPTION_PRIV_INSTRUCTION:
fputs("Error: EXCEPTION_PRIV_INSTRUCTION\n", stderr);
break;
case EXCEPTION_SINGLE_STEP:
fputs("Error: EXCEPTION_SINGLE_STEP\n", stderr);
break;
case EXCEPTION_STACK_OVERFLOW:
fputs("Error: EXCEPTION_STACK_OVERFLOW\n", stderr);
break;
default:
fputs("Error: Unrecognized Exception\n", stderr);
break;
}
fflush(stderr);
if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
{
// TODO : ...
//windows_print_stacktrace(ExceptionInfo->ContextRecord);
}
return EXCEPTION_EXECUTE_HANDLER;
}
#include <windows.h>
#include <imagehlp.h>
void windows_print_stacktrace(CONTEXT* context)
{
SymInitialize(GetCurrentProcess(), 0, true);
STACKFRAME frame = { 0 };
/* setup initial stack frame */
frame.AddrPC.Offset = context->Eip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrStack.Offset = context->Esp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context->Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
while (StackWalk(IMAGE_FILE_MACHINE_I386 ,
GetCurrentProcess(),
GetCurrentThread(),
&frame,
context,
0,
SymFunctionTableAccess,
SymGetModuleBase,
0 ) )
{
addr2line(global_program_name, (void*)frame.AddrPC.Offset);
}
SymCleanup( GetCurrentProcess() );
}
但是:
#include <execinfo.h>
#include <signal.h>
static void handler(int sig)
{
// Catch exceptions
switch(sig)
{
case SIGABRT:
fputs("Caught SIGABRT: usually caused by an abort() or assert()\n", stderr);
break;
case SIGFPE:
fputs("Caught SIGFPE: arithmetic exception, such as divide by zero\n",
stderr);
break;
case SIGILL:
fputs("Caught SIGILL: illegal instruction\n", stderr);
break;
case SIGINT:
fputs("Caught SIGINT: interactive attention signal, probably a ctrl+c\n",
stderr);
break;
case SIGSEGV:
fputs("Caught SIGSEGV: segfault\n", stderr);
break;
case SIGTERM:
default:
fputs("Caught SIGTERM: a termination request was sent to the program\n",
stderr);
break;
}
// Print stacktrace
void *array[10];
size_t size;
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// Ctrl+C interrupt => No backtrace
if (sig != (int)SIGINT) {
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, 2);
}
exit(sig);
}
signal(SIGABRT, handler);
signal(SIGFPE, handler);
signal(SIGILL, handler);
signal(SIGINT, handler);
signal(SIGSEGV, handler);
signal(SIGTERM, handler);
#include <windows.h>
static LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS * ExceptionInfo)
{
switch(ExceptionInfo->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
fputs("Error: EXCEPTION_ACCESS_VIOLATION\n", stderr);
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
fputs("Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED\n", stderr);
break;
case EXCEPTION_BREAKPOINT:
fputs("Error: EXCEPTION_BREAKPOINT\n", stderr);
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
fputs("Error: EXCEPTION_DATATYPE_MISALIGNMENT\n", stderr);
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
fputs("Error: EXCEPTION_FLT_DENORMAL_OPERAND\n", stderr);
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
fputs("Error: EXCEPTION_FLT_DIVIDE_BY_ZERO\n", stderr);
break;
case EXCEPTION_FLT_INEXACT_RESULT:
fputs("Error: EXCEPTION_FLT_INEXACT_RESULT\n", stderr);
break;
case EXCEPTION_FLT_INVALID_OPERATION:
fputs("Error: EXCEPTION_FLT_INVALID_OPERATION\n", stderr);
break;
case EXCEPTION_FLT_OVERFLOW:
fputs("Error: EXCEPTION_FLT_OVERFLOW\n", stderr);
break;
case EXCEPTION_FLT_STACK_CHECK:
fputs("Error: EXCEPTION_FLT_STACK_CHECK\n", stderr);
break;
case EXCEPTION_FLT_UNDERFLOW:
fputs("Error: EXCEPTION_FLT_UNDERFLOW\n", stderr);
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
fputs("Error: EXCEPTION_ILLEGAL_INSTRUCTION\n", stderr);
break;
case EXCEPTION_IN_PAGE_ERROR:
fputs("Error: EXCEPTION_IN_PAGE_ERROR\n", stderr);
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
fputs("Error: EXCEPTION_INT_DIVIDE_BY_ZERO\n", stderr);
break;
case EXCEPTION_INT_OVERFLOW:
fputs("Error: EXCEPTION_INT_OVERFLOW\n", stderr);
break;
case EXCEPTION_INVALID_DISPOSITION:
fputs("Error: EXCEPTION_INVALID_DISPOSITION\n", stderr);
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
fputs("Error: EXCEPTION_NONCONTINUABLE_EXCEPTION\n", stderr);
break;
case EXCEPTION_PRIV_INSTRUCTION:
fputs("Error: EXCEPTION_PRIV_INSTRUCTION\n", stderr);
break;
case EXCEPTION_SINGLE_STEP:
fputs("Error: EXCEPTION_SINGLE_STEP\n", stderr);
break;
case EXCEPTION_STACK_OVERFLOW:
fputs("Error: EXCEPTION_STACK_OVERFLOW\n", stderr);
break;
default:
fputs("Error: Unrecognized Exception\n", stderr);
break;
}
fflush(stderr);
if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
{
// TODO : ...
//windows_print_stacktrace(ExceptionInfo->ContextRecord);
}
return EXCEPTION_EXECUTE_HANDLER;
}
#include <windows.h>
#include <imagehlp.h>
void windows_print_stacktrace(CONTEXT* context)
{
SymInitialize(GetCurrentProcess(), 0, true);
STACKFRAME frame = { 0 };
/* setup initial stack frame */
frame.AddrPC.Offset = context->Eip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrStack.Offset = context->Esp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context->Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
while (StackWalk(IMAGE_FILE_MACHINE_I386 ,
GetCurrentProcess(),
GetCurrentThread(),
&frame,
context,
0,
SymFunctionTableAccess,
SymGetModuleBase,
0 ) )
{
addr2line(global_program_name, (void*)frame.AddrPC.Offset);
}
SymCleanup( GetCurrentProcess() );
}
MinGW没有backtrace
,也没有backtrace\u符号
功能。上面需要知道global\u program\u name
,因为管理异常的代码位于主程序加载的dll
中,所以我没有这个名称
所以问题:
#include <execinfo.h>
#include <signal.h>
static void handler(int sig)
{
// Catch exceptions
switch(sig)
{
case SIGABRT:
fputs("Caught SIGABRT: usually caused by an abort() or assert()\n", stderr);
break;
case SIGFPE:
fputs("Caught SIGFPE: arithmetic exception, such as divide by zero\n",
stderr);
break;
case SIGILL:
fputs("Caught SIGILL: illegal instruction\n", stderr);
break;
case SIGINT:
fputs("Caught SIGINT: interactive attention signal, probably a ctrl+c\n",
stderr);
break;
case SIGSEGV:
fputs("Caught SIGSEGV: segfault\n", stderr);
break;
case SIGTERM:
default:
fputs("Caught SIGTERM: a termination request was sent to the program\n",
stderr);
break;
}
// Print stacktrace
void *array[10];
size_t size;
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// Ctrl+C interrupt => No backtrace
if (sig != (int)SIGINT) {
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, 2);
}
exit(sig);
}
signal(SIGABRT, handler);
signal(SIGFPE, handler);
signal(SIGILL, handler);
signal(SIGINT, handler);
signal(SIGSEGV, handler);
signal(SIGTERM, handler);
#include <windows.h>
static LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS * ExceptionInfo)
{
switch(ExceptionInfo->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
fputs("Error: EXCEPTION_ACCESS_VIOLATION\n", stderr);
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
fputs("Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED\n", stderr);
break;
case EXCEPTION_BREAKPOINT:
fputs("Error: EXCEPTION_BREAKPOINT\n", stderr);
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
fputs("Error: EXCEPTION_DATATYPE_MISALIGNMENT\n", stderr);
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
fputs("Error: EXCEPTION_FLT_DENORMAL_OPERAND\n", stderr);
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
fputs("Error: EXCEPTION_FLT_DIVIDE_BY_ZERO\n", stderr);
break;
case EXCEPTION_FLT_INEXACT_RESULT:
fputs("Error: EXCEPTION_FLT_INEXACT_RESULT\n", stderr);
break;
case EXCEPTION_FLT_INVALID_OPERATION:
fputs("Error: EXCEPTION_FLT_INVALID_OPERATION\n", stderr);
break;
case EXCEPTION_FLT_OVERFLOW:
fputs("Error: EXCEPTION_FLT_OVERFLOW\n", stderr);
break;
case EXCEPTION_FLT_STACK_CHECK:
fputs("Error: EXCEPTION_FLT_STACK_CHECK\n", stderr);
break;
case EXCEPTION_FLT_UNDERFLOW:
fputs("Error: EXCEPTION_FLT_UNDERFLOW\n", stderr);
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
fputs("Error: EXCEPTION_ILLEGAL_INSTRUCTION\n", stderr);
break;
case EXCEPTION_IN_PAGE_ERROR:
fputs("Error: EXCEPTION_IN_PAGE_ERROR\n", stderr);
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
fputs("Error: EXCEPTION_INT_DIVIDE_BY_ZERO\n", stderr);
break;
case EXCEPTION_INT_OVERFLOW:
fputs("Error: EXCEPTION_INT_OVERFLOW\n", stderr);
break;
case EXCEPTION_INVALID_DISPOSITION:
fputs("Error: EXCEPTION_INVALID_DISPOSITION\n", stderr);
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
fputs("Error: EXCEPTION_NONCONTINUABLE_EXCEPTION\n", stderr);
break;
case EXCEPTION_PRIV_INSTRUCTION:
fputs("Error: EXCEPTION_PRIV_INSTRUCTION\n", stderr);
break;
case EXCEPTION_SINGLE_STEP:
fputs("Error: EXCEPTION_SINGLE_STEP\n", stderr);
break;
case EXCEPTION_STACK_OVERFLOW:
fputs("Error: EXCEPTION_STACK_OVERFLOW\n", stderr);
break;
default:
fputs("Error: Unrecognized Exception\n", stderr);
break;
}
fflush(stderr);
if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
{
// TODO : ...
//windows_print_stacktrace(ExceptionInfo->ContextRecord);
}
return EXCEPTION_EXECUTE_HANDLER;
}
#include <windows.h>
#include <imagehlp.h>
void windows_print_stacktrace(CONTEXT* context)
{
SymInitialize(GetCurrentProcess(), 0, true);
STACKFRAME frame = { 0 };
/* setup initial stack frame */
frame.AddrPC.Offset = context->Eip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrStack.Offset = context->Esp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context->Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
while (StackWalk(IMAGE_FILE_MACHINE_I386 ,
GetCurrentProcess(),
GetCurrentThread(),
&frame,
context,
0,
SymFunctionTableAccess,
SymGetModuleBase,
0 ) )
{
addr2line(global_program_name, (void*)frame.AddrPC.Offset);
}
SymCleanup( GetCurrentProcess() );
}
是否有办法从dll动态获取全局\u程序\u名称
?如果不是,那么哪种方法是使用MinGW打印stacktrace的好方法
Nota Bene:另一个次要问题是在这一点上取笑我。要获得良好的堆栈跟踪,我需要启用-g
编译器选项。我使用它是否会获得性能的提升(即使我将优化保持在最大值-O3
)?还是我只是影响了共享库的大小
感谢您在这方面的帮助。在Windows平台上,您可以使用全局\uu argv
变量获取程序名
#include <stdlib.h>
addr2line(__argv[0], addr);
#包括
addr2line(_argv[0],addr);
虽然前面的答案有时可能有效,但在许多情况下可能会失败。Argv[0]是在调用execve类型函数(包括windows变体)时可以传递的命令行参数。要可靠地获取可执行文件,请使用以下代码:
TCHAR szExeFileName[MAX_PATH];
GetModuleFileName(NULL, szExeFileName, MAX_PATH);
您可以包含所有的堆栈,而不是为其中的一个重要部分调用外部进程。用户链接dll并使用内置功能创建自己的程序。在此上下文中,stacktrace主要用于捕获(由我)从dll抛出的异常。在我的问题中,我应该先说这个。或者可能我没有理解您所指的代码?换句话说,dll的用户不必在其主程序中处理任何其他代码…抱歉,我有点累:),您只是想利用系统调用
addr2line
并使用示例代码显示堆栈。我试试看。非常感谢。好的,谢谢。但是为什么要在Windows平台上删除?我无法在Linux(gcc(Debian 4.7.2-4)4.7.2)下识别它。另外,MinGW附带的stdlib.h
也可以在其他平台上使用,但并不特别适用于Linux。我正在验证,但忘记添加其他平台注释;)在我的配置中,对于Linux部分,这更像是。感谢MinGW解决方案;-)