


























#include <execinfo.h>
#include <signal.h>
#include <ucontext.h>
#include <cxxabi.h>
#include <stdio.h>
// 崩溃堆栈打印功能 static const int MAX_STACK_FRAMES = 128; /** * @brief 信号处理函数,用于捕获崩溃信号并打印堆栈信息 */ void SignalHandler(int sig, siginfo_t* info, void* context) { void* array[MAX_STACK_FRAMES]; char** messages; int size, i; ucontext_t* ucontext = (ucontext_t*)context; printf("\n\n=== 程序崩溃,开始打印堆栈信息 ===\n"); printf("捕获到信号 %d:\n", sig); switch(sig) { case SIGSEGV: printf("信号: SIGSEGV (段错误/内存访问违规)\n"); break; case SIGABRT: printf("信号: SIGABRT (程序异常终止)\n"); break; case SIGFPE: printf("信号: SIGFPE (算术运算错误)\n"); break; case SIGILL: printf("信号: SIGILL (非法指令)\n"); break; case SIGBUS: printf("信号: SIGBUS (总线错误)\n"); break; default: printf("信号: %d\n", sig); break; } if (info) { printf("错误地址: %p\n", info->si_addr); } if (ucontext) { #if defined(__x86_64__) printf("指令指针: %p\n", (void*)ucontext->uc_mcontext.gregs[REG_RIP]); #elif defined(__i386__) printf("指令指针: %p\n", (void*)ucontext->uc_mcontext.gregs[REG_EIP]); #elif defined(__aarch64__) printf("指令指针: %p\n", (void*)ucontext->uc_mcontext.pc); #endif } // 获取堆栈信息 size = backtrace(array, MAX_STACK_FRAMES); messages = backtrace_symbols(array, size); printf("\n堆栈跟踪 (%d 帧):\n", size); for(i = 0; i < size; i++) { printf("[%02d] %s\n", i, messages[i]); // 尝试demangle C++符号 char* begin_name = nullptr; char* begin_offset = nullptr; char* end_offset = nullptr; // 查找函数名的开始和结束位置 for(char* p = messages[i]; *p; ++p) { if(*p == '(') { begin_name = p; } else if(*p == '+' && begin_name) { begin_offset = p; } else if(*p == ')' && begin_offset) { end_offset = p; break; } } if(begin_name && begin_offset && end_offset && begin_name < begin_offset) { *begin_name++ = '\0'; *begin_offset++ = '\0'; *end_offset = '\0'; int status; char* demangled_name = abi::__cxa_demangle(begin_name, nullptr, nullptr, &status); if(status == 0 && demangled_name) { printf(" 函数: %s\n", demangled_name); free(demangled_name); } else { printf(" 函数: %s\n", begin_name); } } } free(messages); printf("=== 堆栈信息打印结束 ===\n\n"); // 退出程序 exit(sig); } /** * @brief 安装信号处理器 */ void InstallSignalHandler() { struct sigaction sa; sa.sa_sigaction = SignalHandler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART | SA_SIGINFO; // 注册需要捕获的信号 sigaction(SIGSEGV, &sa, nullptr); // 段错误 sigaction(SIGABRT, &sa, nullptr); // 异常终止 sigaction(SIGFPE, &sa, nullptr); // 算术异常 sigaction(SIGILL, &sa, nullptr); // 非法指令 sigaction(SIGBUS, &sa, nullptr); // 总线错误 }
main函数中执行安装句柄函数
int main(int argc, char* argv[]) { InstallSignalHandler(); printf("崩溃堆栈打印功能已启用\n"); }
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。