如何使用 gcc 获取带有行号信息的 C++ 堆栈跟踪? [复制]

2023-11-23

我们使用专有的堆栈跟踪assert就像捕获开发人员错误的宏一样 - 当捕获错误时,会打印堆栈跟踪。

我找到了 gcc 的对backtrace()/backtrace_symbols()方法不足:

  1. 名字被破坏了
  2. 无线路信息

第一个问题可以通过以下方式解决abi::__cxa_demangle.

然而第二个问题更难。我发现替换 backtrace_symbols()。 这比 gcc 的 backtrace_symbols() 更好,因为它可以检索行号(如果使用 -g 编译)并且不需要使用 -rdynamic 进行编译。

Hoverer 代码是 GNU 许可的,所以恕我直言,我不能在商业代码中使用它。

有什么建议吗?

P.S.

gdb 能够打印出传递给函数的参数。 可能要求已经太多了:)

PS 2

类似问题(谢谢诺巴尔)


所以你想要一个打印堆栈跟踪的独立函数具有 gdb 堆栈跟踪所具有的所有功能,并且不会终止您的应用程序。答案是以非交互模式自动启动 gdb 以执行您想要的任务。

这是通过在子进程中执行 gdb、使用 fork() 并编写脚本来在应用程序等待其完成时显示堆栈跟踪来完成的。这可以在不使用核心转储且不中止应用程序的情况下执行。我通过查看这个问题学会了如何做到这一点:从程序中调用 gdb 来打印它的堆栈跟踪如何更好?

与该问题一起发布的示例并不完全按照所写的那样对我起作用,所以这是我的“固定”版本(我在 Ubuntu 9.04 上运行了这个)。

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/prctl.h>

void print_trace() {
    char pid_buf[30];
    sprintf(pid_buf, "%d", getpid());
    char name_buf[512];
    name_buf[readlink("/proc/self/exe", name_buf, 511)]=0;
    prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
    int child_pid = fork();
    if (!child_pid) {
        dup2(2,1); // redirect output to stderr - edit: unnecessary?
        execl("/usr/bin/gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
        abort(); /* If gdb failed to start */
    } else {
        waitpid(child_pid,NULL,0);
    }
}

如引用的问题所示,gdb 提供了您可以使用的其他选项。例如,使用“bt full”而不是“bt”会生成更详细的报告(局部变量包含在输出中)。 gdb 的联机帮助页比较简单,但提供了完整的文档here.

由于这是基于 gdb 的,因此输出包括分解的名字, 行号, 函数参数,并且可选地甚至局部变量。此外,gdb 是线程感知的,因此您应该能够提取一些特定于线程的元数据。

这是我使用此方法看到的堆栈跟踪类型的示例。

0x00007f97e1fc2925 in waitpid () from /lib/libc.so.6
[Current thread is 0 (process 15573)]
#0  0x00007f97e1fc2925 in waitpid () from /lib/libc.so.6
#1  0x0000000000400bd5 in print_trace () at ./demo3b.cpp:496
2  0x0000000000400c09 in recursive (i=2) at ./demo3b.cpp:636
3  0x0000000000400c1a in recursive (i=1) at ./demo3b.cpp:646
4  0x0000000000400c1a in recursive (i=0) at ./demo3b.cpp:646
5  0x0000000000400c46 in main (argc=1, argv=0x7fffe3b2b5b8) at ./demo3b.cpp:70

注意:我发现这与使用不兼容valgrind(可能是由于 Valgrind 使用虚拟机)。当您在 gdb 会话内运行程序时,它也不起作用(无法将“ptrace”的第二个实例应用于进程)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 gcc 获取带有行号信息的 C++ 堆栈跟踪? [复制] 的相关文章

  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • 在 .gitconfig 中隐藏 GitHub 令牌

    我想将所有点文件存储在 GitHub 上 包括 gitconfig 这需要我将 GitHub 令牌隐藏在 gitconfig 中 为此 我有一个 gitconfig hidden token 文件 这是我打算编辑并放在隐藏令牌的 git 下
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 我们真的应该使用 Chef 来管理 sudoers 文件吗?

    这是我的问题 我担心如果 Chef 破坏了 sudoers 文件中的某些内容 可能是 Chef 用户错误地使用了说明书 那么服务器将完全无法访问 我讨厌我们完全失去客户的生产服务器 因为我们弄乱了 sudoers 文件并且无法再通过 ssh
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • GCC 如何运行其他程序?

    也许标题并没有那么准确地表达问题 我知道当我跑步时gcc foo cGCC 调用其他为其完成所有工作的子程序 使 gcc 主程序只是一个接口 但这到底是如何完成的呢 是否使用system or exec或者其他一些功能 我之所以想知道这个是
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐

  • 如何在自托管 Windows 代理上从 Azure DevOps 管道运行 Azure CLI 任务?

    情况 我的自托管 Windows 代理运行来自 Azure DevOps 的管道 到 管理 Azure 中的资源 我想使用 Azure CLI 任务 即使在前面的步骤中安装了 Azure CLI AzureCLI 任务也会失败 我有两个从我
  • 以编程方式执行单击 Actor libgdx

    我的问题很简单 我有一些ClickListener添加到 Actor 中 我想以编程方式对它们执行单击事件 就像是myActor performClick 您还可以使用 InputEvent event1 new InputEvent ev
  • 获取 SelectOneMenu 的选定值

    我正在 jsf 页面上测试组件 SelectOneMenu 我通过我的 ManageBean 动态地填充这个组件 将从数据库中获取所有动物 我想知道是否可以看到用户选择的 SelectOneMenu 组合框 项目 我正在尝试使用 value
  • 有主机和无主机的入口

    理解和调试入口规则确实变得越来越困难 有人可以分享一个好的参考吗 问题是在不指定主机的情况下入口如何工作 apiVersion extensions v1beta1 kind Ingress metadata annotations ngi
  • 如何使用git拉取特定目录

    我有一个使用 git 的项目 我只想克隆或拉取特定目录 例如 myproject javascript 就像 subversion 一样 进行一些更改 提交并再次推回 这是可能的 cd 到您的存储库副本的顶部 git fetch git c
  • 比较两个数组 Javascript - 关联

    我在这里搜索了一种比较 javascript 中关联数组的质量方法 我发现的唯一合适的解决方案是PHP JS项目具有一些比较数组功能 唯一的问题是这些函数将第一个数组视为第二个数组的键 在我的情况下 至少两个数组并不总是具有相同的键数或相同
  • ng-重复完成事件

    我想调用一些针对 div 和 table 的 jQuery 函数 该表填充有ng repeat 当我打电话时 document ready 我没有结果 Also scope on viewContentLoaded myFunc 没有帮助
  • 使用 ssl 模块的 HTTPS 代理隧道

    我想手动 使用socket and ssl模块 制作一个HTTPS通过本身使用的代理请求HTTPS 我可以执行初始操作CONNECT交换就好 import ssl socket PROXY ADDR proxy addr 443 CONNE
  • XSLT:将分组 html 元素移动到节级别

    我正在尝试编写一个 XSLT 根据标头级别将 HTML 文件组织为不同的部分级别 这是我的输入 h1 HEADER 1 CONTENT h1 p Level 1 para p p Level 1 para p p Level 1 para
  • 为什么我的随机数总是相同?

    我正在使用random numberFortran 的子例程 但在程序的不同运行中 生成的数字不会改变 我应该在代码中包含什么 以便每次编译和运行程序时数字都会发生变化 随机数生成器产生伪随机数 要每次运行获得不同的数字 您需要初始化随机种
  • 将 WPF 绑定错误转换为运行时异常。不适用于已发布的已发布应用程序

    我想将数据绑定错误记录到文件中 我使用了这个接受的答案中提出的解决方案 如何将绑定错误转化为运行时异常 我也尝试过这个 http msdn microsoft com en us library system diagnostics pre
  • javax.crypto 在不同版本的 Android 操作系统中工作方式不同吗?

    我使用此代码片段来加密 解密应用程序数据库中的数据 http www androidsnippets com encryptdecrypt strings 看来 javax crypto KeyGenerator generateKey 操
  • 在 JIRA REST API 中启用 CORS

    我在 Confluence 用户宏中从 JavaScript 调用 JIRA REST API 并且面临 CORS 问题 因为 JIRA 和 Confluence 位于两个不同的域中 并且飞行前请求从浏览器失败 我已经尝试了如下所述的几种
  • 多次构造的 Eager ApplicationScoped 托管 bean

    我有一堆eager ApplicationScoped托管豆 其中一些是通过注射到其他体内的ManagedProperty注解 形成依赖树 每个依赖 bean 在构建后都会操纵其父代 然而 似乎每次注入都会创建一个新实例 从而撤销之前的操作
  • WPF:如何使自定义模式对话框闪烁?

    通常 当您打开模态对话框并尝试单击其父窗口时 模态对话框的标题栏会闪烁 在 WPF 中创建自定义 无边框 无边框窗口时 您将失去所有功能 必须自行重建 我左顾右盼 终生不知道如何让我的模态窗口闪烁 虽然还是发出嘟嘟的声音 我想我将不得不监视
  • shared_ptr 别名构造函数

    关于关注的问题shared ptr构造函数 template lt class Y gt shared ptr const shared ptr
  • Xcode“-[UIViewController _loadViewFromNibNamed:bundle:] 加载了笔尖,但未设置视图出口。”错误

    我正在使用 Xcode 4 当我运行我的应用程序时 第一个屏幕无法加载 它在模拟器和设备上失败 我已经搜索了答案 他们都说要确保我已将文件所有者中的圆圈拖动到正确的视图 抱歉 我不记得这些东西的名称了 我是 Xcode 新手 我已将圆圈拖动
  • 将参数从 vbscript 传递到批处理文件

    您好 我在通过 vbscript 将参数传递到批处理文件时遇到问题 我不太擅长编程 所以我确信我只是错过了一些愚蠢的东西 无论如何 我正在使用 vbscript 来无形地运行批处理文件 vb脚本被称为 C Program Files x86
  • 播放 Soundcloud 嵌入时暂停 Youtube 嵌入

    我有一个音乐博客 其中包含各种嵌入式 soundcloud 和 youtube 播放器 我想要做的是防止任何音频同时播放 换句话说 当我正在播放 YouTube 视频时 如果我单击播放嵌入的 soundcloud 我希望 YouTube 播
  • 如何使用 gcc 获取带有行号信息的 C++ 堆栈跟踪? [复制]

    这个问题在这里已经有答案了 我们使用专有的堆栈跟踪assert就像捕获开发人员错误的宏一样 当捕获错误时 会打印堆栈跟踪 我找到了 gcc 的对backtrace backtrace symbols 方法不足 名字被破坏了 无线路信息 第一