在Windows/Linux/MacOS C++程序中打印崩溃调用栈和局部变量信息
打印崩溃调用栈和局部变量信息的方法有所不同。以下是针对 Windows、Linux 和 MacOS 的示例代码。
Windows
在 Windows 上,可以使用 Windows API 来捕获异常并打印调用栈。
#include <windows.h>
#include <DbgHelp.h>
#include <stdio.h>
#include <stdlib.h>#pragma comment(lib, "dbghelp.lib")void print_stack_trace() {const int FRAMES_TO_CAPTURE = 64;IMAGEHLP_STACK_FRAME frames[FRAMES_TO_CAPTURE];STACKFRAME64 stack;DWORD machine_type;HANDLE process = GetCurrentProcess();DWORD i;SYMBOL_INFOW* symbol_info;DWORD64 displacement;SymInitialize(process, NULL, TRUE);SymSetOptions(SYMOPT_UNDNAME | SYMOPT_LOAD_LINES);ZeroMemory(&stack, sizeof(stack));stack.AddrPC.Offset = (DWORD_PTR)__debugbreak;stack.AddrPC.Mode = AddrModeFlat;stack.AddrFrame.Offset = (DWORD_PTR)__security_check_cookie;stack.AddrFrame.Mode = AddrModeFlat;stack.AddrStack.Offset = (DWORD_PTR)&stack;stack.AddrStack.Mode = AddrModeFlat;machine_type = IMAGE_FILE_MACHINE_UNKNOWN;if (!StackWalk64(machine_type, process, GetCurrentThread(), &stack)) {machine_type = IMAGE_FILE_MACHINE_I386;if (!StackWalk64(machine_type, process, GetCurrentThread(), &stack)) {machine_type = IMAGE_FILE_MACHINE_AMD64;if (!StackWalk64(machine_type, process, GetCurrentThread(), &stack)) {fprintf(stderr, "Failed to determine machine type\n");return;}}}symbol_info = (SYMBOL_INFOW*)calloc(sizeof(SYMBOL_INFOW) + 256 * sizeof(wchar_t), 1);if (symbol_info == NULL) {fprintf(stderr, "Failed to allocate memory for symbol_info\n");return;}symbol_info->MaxNameLen = 255;symbol_info->SizeOfStruct = sizeof(SYMBOL_INFOW);for (i = 0; i < FRAMES_TO_CAPTURE; i++) {if (!StackWalk64(machine_type, process, GetCurrentThread(), &stack)) {break;}if (!SymFromAddr(process, stack.AddrPC.Offset, &displacement, symbol_info)) {fprintf(stderr, "Frame %d: 0x%llx\n", i, stack.AddrPC.Offset);} else {fwprintf(stderr, L"Frame %d: %ls + 0x%llx\n", i, symbol_info->Name, displacement);}// Print local variables here, but it's tricky without proper debugging symbols}free(symbol_info);SymCleanup(process);
}void cause_crash() {int *p = NULL;*p = 1;
}int main() {__try {cause_crash();}__except (print_stack_trace(), EXCEPTION_EXECUTE_HANDLER) {exit(EXIT_FAILURE);}return 0;
}
Linux
在 Linux 上,可以使用信号处理和 backtrace 函数来捕获崩溃并打印调用栈。
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <execinfo.h>
#include <unistd.h>void print_stack_trace() {void *array[10];size_t size;char **strings;size_t i;size = backtrace(array, 10);strings = backtrace_symbols(array, size);printf("Stack backtrace:\n");for (i = 0; i < size; i++) {printf("[bt] %s\n", strings[i]);}free(strings);
}void signal_handler(int sig) {print_stack_trace();exit(EXIT_FAILURE);
}void cause_crash() {int *p = NULL;*p = 1;
}int main() {signal(SIGSEGV, signal_handler);cause_crash();return 0;
}
MacOS
在 MacOS 上,可以使用类似 Linux 的方法,使用 backtrace 和 backtrace_symbols 函数。
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <execinfo.h>
#include <unistd.h>void print_stack_trace() {void *array[10];size_t size;char **strings;size_t i;size = backtrace(array, 10);strings = backtrace_symbols(array, size);printf("Stack backtrace:\n");for (i = 0; i < size; i++) {printf("[bt] %s\n", strings[i]);}free(strings);
}void signal_handler(int sig) {print_stack_trace();exit(EXIT_FAILURE);
}void cause_crash() {int *p = NULL;*p = 1;
}int main() {signal(SIGSEGV, signal_handler);cause_crash();return 0;
}
备注
-
局部变量打印:在崩溃时打印局部变量非常困难,因为局部变量可能已经破坏或不可访问。在上述示例中,主要展示了如何打印调用栈信息。要获取局部变量的值,通常需要启用调试信息并使用调试器(如 GDB)来解析堆栈帧。
-
调试符号:为了更详细地解析调用栈和局部变量,需要在编译时启用调试信息,例如在 GCC 中使用
-g选项。 -
平台差异:不同的操作系统有不同的 API 和方法来处理崩溃和调用栈跟踪,因此需要根据具体平台选择相应的方法。
相关文章:
在Windows/Linux/MacOS C++程序中打印崩溃调用栈和局部变量信息
打印崩溃调用栈和局部变量信息的方法有所不同。以下是针对 Windows、Linux 和 MacOS 的示例代码。 Windows 在 Windows 上,可以使用 Windows API 来捕获异常并打印调用栈。 #include <windows.h> #include <DbgHelp.h> #include <stdio.h> #in…...
解决npm install安装出现packages are looking for funding run `npm fund` for details问题
当我们运行npm install时,可能会收到类似以下的提示信息:“x packages are looking for funding.” 这并不是错误提示,也不会影响项目的正常运行。其实实在提醒有一些软件包正在寻求资金支持。 根据提示输入npm fund可以查看详细的信息&#…...
豆包MarsCode:小C点菜问题
问题描述 思路分析 这道题的核心任务是找出所有不超过给定价格 m 的菜肴中,最常见的菜肴价格,最后返回该价格的出现次数。 1. 题意理解: 给定一个最大价格 m,小C只会选择价格不超过 m 的菜。菜单上有 n 道菜,每道菜…...
K8S中Pod控制器之CronJob(CJ)控制器
CronJob 控制器是 Kubernetes 中用于周期性执行任务的一种控制器,它基于 Job 控制器来创建和管理作业。以下是 CronJob 的一些关键特点: 周期性调度:CronJob 允许您定义一个基于时间的调度,类似于 Linux 的 cron 工具,…...
FRP内网穿透0.61.1新版教程
在上一篇zerotier讲述了如何实现虚拟局域网搭建,这篇会讲述FRP内网穿透的使用教程 那么frp与zerotier的区别是什么呢?(说人话) FRP 主要用于内网服务向外网的单向暴露。 ZeroTier 用于构建一个虚拟的私有网络,实现多点…...
亲测解决`data_array` is not of type `MetaTensor, assuming affine to be identity
这个问题是由于orientation的数据增强在scaling之后导致的,解决方法是将这两个数据增强的顺序调换。 问题原文 lib/python3.10/site-packages/monai/transforms/spatial/array.py:623: UserWarning: `data_array` is...
python+pygame+pytmx+map editor开发一个tiled游戏demo 05使用object层初始化player位置
代码 import mathimport pygame# 限制物体在屏幕内 import pytmxdef limit_position_to_screen(x, y, width, height):"""限制物体在屏幕内"""x max(0, min(x, SCREEN_WIDTH - width)) # 限制x坐标y max(0, min(y, SCREEN_HEIGHT - height))…...
Git实用指南:忽略文件、命令别名、版本控制、撤销修改与标签管理
目录 1.忽略特殊文件 1.1.那如何配置我们需要忽略的文件的呢? 1.2.如何检验效果? 2.给命令配置别名 3.基本操作之版本回退 3.1.使用场景: 3.2.使用方法: 4.撤销修改 情况一:对于工作区的代码,还没…...
wordpress安装完后台无格式解决方法(样式加载不出来)
刚安装的wordpress,进入后台后,没有样式。 1.如果ip进入,可能一切正常 2.域名进入,遇到这种情况概率大(经过了nginx代理) 正常访问文章的话是没问题的,只是管理后台存在这样的代码,样式没加载出来。 美国随机地址生成器:美国随机地址生成器(随机地址生成器 - 生成全…...
数据库管理-第285期 Oracle 23ai:深入浅出向量索引(20250117)
数据库管理285期 20245-01-17 数据库管理-第285期 Oracle 23ai:深入浅出向量索引(20250117)1 HNSW事务支持解读 2 IVF分区支持解读 3 混合向量索引何时选择混合向量索引为何选择混合向量索引 总结 数据库管理-第285期 Oracle 23ai:…...
日志(elk stack)基础语法学习,零基础学习
ELK Stack 是一组开源的日志管理工具,包括 Elasticsearch、Logstash 和 Kibana。Elasticsearch 用于存储和搜索日志数据,Logstash 用于收集和处理日志数据,而 Kibana 提供了一个强大的可视化界面来分析和监控这些数据。以下是 ELK Stack 的基…...
Mysql InnoDB B+Tree是什么?
“mysql中常用的数据库搜索引擎InnoDB,其索引通过BTree的方式进行构建。” 实在想不起来BTree是怎么一回事了。以点带线,将涉及到的数据结构一起复习一下。 文章目录 数据结构定义红黑树定义使命 BTree定义使命 BTree定义 InnoDB BTree 旋转与调整二叉排序树插入删…...
Java基础(二)
提示:这部分内容对逆向重要,需重点掌握。 1.常见数据类型 1.1 List系列 类似于Python中的列表 List是一个接口,接口下面有两个常见的类型(目的是可以存放动态的多个数据) ArrayList,连续的内存地址存储(内部自动扩容) -> Python列表的特点LinkedList,底层基于链表…...
【网络协议】【http】【https】TLS1.3
【网络协议】【http】【https】TLS1.3 TLS1.3它的签名算法和密钥交换算法,默认情况下是被固定了下来的,他的加密套件里面呢,只包含了对称加密算法和摘要算法 客户端和服务器第一次连接 仍然需要1RTT ,不能0-RTT 第一次连接 1.客…...
K8S中Pod控制器之Job控制器
Job,主要用于负责批量处理(一次要处理指定数量任务)短暂的一次性(每个任务仅运行一次就结束)任务。 一次性任务:Job 用于运行那些只需要执行一次的任务,如数据分析、图像渲染或批量处理。 成功终止:Job 会跟踪其创建的 Pod 的成功…...
macOS安装Gradle环境
文章目录 说明安装JDK安装Gradle 说明 gradle8.5最高支持jdk21,如果使用jdk22建议使用gradle8.8以上版本 安装JDK mac系统安装最新(截止2024.9.13)Oracle JDK操作记录 安装Gradle 下载Gradle,解压将其存放到资源java/env目录…...
2024年美赛C题评委文章及O奖论文解读 | AI工具如何影响数学建模?从评委和O奖论文出发-O奖论文做对了什么?
模型假设仅仅是简单陈述吗?允许AI的使用是否降低了比赛难度?还在依赖机器学习的模型吗?处理题目的方法有哪些?O奖论文的优点在哪里? 本文调研了当年赛题的评委文章和O奖论文,这些问题都会在文章中一一解答…...
LDD3学习9--数据类型和定时器
这部分对应的是第七章和第十一章,因为内容也不是很多,就一起写了。里面的内容基本上就是一个个的点,所以也就一个个点简单总结一下。 1 数据类型 1.1 数据长度 不同操作系统类型长度可能不一样,看图的话最好用u8,u16&…...
一文夯实垃圾收集的理论基础
如何判断一个引用是否存活 引用计数法 给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使用的。 优点:可即刻回收垃圾&a…...
OpenWRT Conserver 共享串口服务实现
安装驱动 查看当前可在线安装的USB驱动 opkg update 查看安装的USB驱动 opkg list-installed *usb-serial* 查看所有的USB串口驱动 opkg list *usb-serial* 确认console线的芯片厂商 kmod-usb-serial-pl2303 - 5.15.167-1 - Kernel support for Prolific PL2303 USB-to…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
