在C++ 代码中怎么获取函数调用栈信息
发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要介绍"在C++ 代码中怎么获取函数调用栈信息",在日常操作中,相信很多人在在C++ 代码中怎么获取函数调用栈信息问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答
千家信息网最后更新 2026年11月02日在C++ 代码中怎么获取函数调用栈信息
这篇文章主要介绍"在C++ 代码中怎么获取函数调用栈信息",在日常操作中,相信很多人在在C++ 代码中怎么获取函数调用栈信息问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"在C++ 代码中怎么获取函数调用栈信息"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
一、前言
程序在执行过程中 crash 是非常严重的问题,一般都应该在测试阶段排除掉这些问题,但是总会有漏网之鱼被带到 release 阶段。
因此,程序的日志系统需要侦测这种情况,在代码崩溃的时候获取函数调用栈信息,为 debug 提供有效的信息。
二、Linux 平台
1. 注册异常信号的处理函数
需要处理哪些异常信号
#include#include #include const std::map Signals = { {SIGINT, "SIGINT"}, {SIGABRT, "SIGABRT"}, {SIGFPE, "SIGFPE"}, {SIGILL, "SIGILL"}, {SIGSEGV, "SIGSEGV"} // 可以添加其他信号 };
注册信号处理函数
struct sigaction action; sigemptyset(&action.sa_mask); action.sa_sigaction = &sigHandler; action.sa_flags = SA_SIGINFO; for (const auto &sigPair : Signals) { if (sigaction(sigPair.first, &action, NULL) < 0) fprintf(stderr, "Error: sigaction failed! \n"); }2. 捕获异常,获取函数调用栈信息
void sigHandler(int signum, siginfo_t *info, void *ctx) { const size_t dump_size = 50; void *array[dump_size]; int size = backtrace(array, dump_size); char **symbols = backtrace_symbols(array, size); std::ostringstream oss; for (int i = 0; i < size; ++i) { char *mangleName = 0; char *offsetBegin = 0; char *offsetEnd = 0; for (char *p = symbols[i]; *p; ++p) { if ('(' == *p) { mangleName = p; } else if ('+' == *p) { offsetBegin = p; } else if (')' == *p) { offsetEnd = p; break; } } if (mangleName && offsetBegin && offsetEnd && mangleName < offsetBegin) { *mangleName++ = '\0'; *offsetBegin++ = '\0'; *offsetEnd++ = '\0'; int status; char *realName = abi::__cxa_demangle(mangleName, 0, 0, &status); if (0 == status) oss << "\tstack dump [" << i << "] " << symbols[i] << " : " << realName << "+"; else oss << "\tstack dump [" << i << "] " << symbols[i] << mangleName << "+"; oss << offsetBegin << offsetEnd << std::endl; free(realName); } else { oss << "\tstack dump [" << i << "] " << symbols[i] << std::endl; } } free(symbols); oss << std::endl; std::cout << oss.str(); // 打印函数调用栈信息 }三、Windwos 平台
在 Windows 平台下的代码实现,参考了国外某个老兄的代码,如下:
1. 设置异常处理函数
#include#include SetUnhandledExceptionFilter(exceptionHandler);
2. 捕获异常,获取函数调用栈信息
void exceptionHandler(LPEXCEPTION_POINTERS info) { CONTEXT *context = info->ContextRecord; std::shared_ptr RaiiSysCleaner(nullptr, [&](void *) { SymCleanup(GetCurrentProcess()); }); const size_t dumpSize = 64; std::vector frameVector(dumpSize); DWORD machine_type = 0; STACKFRAME64 frame = {}; frame.AddrPC.Mode = AddrModeFlat; frame.AddrFrame.Mode = AddrModeFlat; frame.AddrStack.Mode = AddrModeFlat; #ifdef _M_IX86 frame.AddrPC.Offset = context->Eip; frame.AddrFrame.Offset = context->Ebp; frame.AddrStack.Offset = context->Esp; machine_type = IMAGE_FILE_MACHINE_I386; #elif _M_X64 frame.AddrPC.Offset = context->Rip; frame.AddrFrame.Offset = context->Rbp; frame.AddrStack.Offset = context->Rsp; machine_type = IMAGE_FILE_MACHINE_AMD64; #elif _M_IA64 frame.AddrPC.Offset = context->StIIP; frame.AddrFrame.Offset = context->IntSp; frame.AddrStack.Offset = context->IntSp; machine_type = IMAGE_FILE_MACHINE_IA64; frame.AddrBStore.Offset = context.RsBSP; frame.AddrBStore.Mode = AddrModeFlat; #else frame.AddrPC.Offset = context->Eip; frame.AddrFrame.Offset = context->Ebp; frame.AddrStack.Offset = context->Esp; machine_type = IMAGE_FILE_MACHINE_I386; #endif for (size_t index = 0; index < frameVector.size(); ++index) { if (StackWalk64(machine_type, GetCurrentProcess(), GetCurrentThread(), &frame, context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) { frameVector[index] = frame.AddrPC.Offset; } else { break; } } std::string dump; const size_t kSize = frameVector.size(); for (size_t index = 0; index < kSize && frameVector[index]; ++index) { dump += getSymbolInfo(index, frameVector); dump += "\n"; } std::cout << dump; } 主要是利用了 StackWalk64 这个函数,从地址转换为函数名称。
到此,关于"在C++ 代码中怎么获取函数调用栈信息"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
函数
信息
代码
C++
信号
处理
学习
平台
问题
更多
程序
阶段
帮助
实用
有效
接下来
漏网之鱼
信号处理
前言
名称
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
花魁咖啡
科技互联网企业
互联网 科技公司
互联网科技小贷
智网互联网科技
远信互联网科技
贷财互联网科技
电子科技大学互联网
互联网科技logo
华脉科技工业互联网产品
中国最先进互联网科技公司
互联网科技寓意
花神(南京)互联网科技有限公司
消费医药和互联网科技
燊美集互联网科技有限公司
互联网新科技动漫ppt素材
国大互联网教育科技有限公司薪资
从那以后互联网科技有限公司
互联网科技新闻
恒生科技互联网指数十大成分股
花魁咖啡
互联网科技公司发展
互联网科技大会案例
云创客互联网科技公司
哈尔滨新华互联网科技学院
湖北码尼互联网科技有限公司电话
和信科技工业互联网
互联网与医疗科技
互联网科技股为什么大涨
兰石爱特工业互联网科技分公司