问题标签 [dwarf]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
1991 浏览

c - 如何获取 C 函数指针的函数名

我有以下问题:当我在 C 中使用 backtrace(3) 函数获得回溯时,返回函数名称的符号很容易通过 dwarf 库和 dladdr(3) 确定。

问题是,如果我有一个简单的函数指针(例如通过传递它&function),dladdr + dwarf 函数将无济于事。似乎指针与 backtrace(3) 返回的指针不同(这并不奇怪,因为 backtrace 直接从堆栈中获取这些函数指针)。

我的问题是是否也有一些方法可以解决这些名称?另外,我想确切地知道这两个指针之间有什么区别。

谢谢!

更新:

指针之间的区别非常显着:
我用回溯得到的是:0x8048ca4
直接指针版本:0x3ba838

在我看来,第二个需要一个偏移量。

0 投票
3 回答
783 浏览

stack-unwinding - 使用 dwarf2 展开堆栈时获取堆栈指针的值

在 DWARF2 调试格式中,借助 .debug_frame 部分中的 CFI(调用帧信息)支持堆栈展开。这正是一个表格,它为每个寄存器在前一帧中获取其值保留了一条规则。但是,所有这些规则都依赖于寄存器保存在堆栈中某个位置的事实。当没有帧指针时,这对于在前一帧寄存器中获取堆栈指针的值是不正确的。在这种情况下,堆栈指针可能不会保存在堆栈上,而只是通过递增和递减其值来管理。但是,在 dwarf2(或一般的 dwarf 格式)中没有办法表明寄存器值是其当前值的表达式。所以,我的问题是,如何在使用 dwarf2 调试格式的堆栈展开期间获取堆栈指针的值(当没有帧指针时)。

-BV

0 投票
1 回答
672 浏览

debugging - dwarf2中的堆栈展开

我不明白 dwarf2 中的堆栈展开如何确保在一些非常基本的 ABI(应用程序二进制接口)场景中可靠地恢复参数。考虑一个 ABI,它表示前三个参数必须在寄存器上并且在堆栈上。据我了解,dwarf2 堆栈展开机制确保如果 CFI 表被正确填充,则可以在当前帧的调用点获取寄存器的值。但是,这并不能让您进入调用者的序言并知道参数寄存器的内容是什么。所以,我认为应该有一种方法可以在不同点的同一帧中找到寄存器的值(在 .debug_frame 部分中编码的表只给出了前一帧中的位置)。

我的理解有什么问题吗?在这种情况下,基于 dwarf2 调试格式的调试器如何工作?对于在堆栈上传递参数的架构,恢复程序中所有点的值(对于任何帧)不会有任何问题。

0 投票
2 回答
1873 浏览

debugging - 使用 DWARF 信息将内存地址映射到行号

我有一个通过内存跟踪程序执行的应用程序。我试图用来readelf --debug-dump=decodedline获取内存地址/行号信息,但我看到的内存地址与该转储给出的内存地址不匹配。我写了一些东西来将每个地址与 DWARF 数据中出现的“最新”地址相匹配——这似乎清理了一些东西,但我不确定这是否是解释这些数据的“官方”方式。

有人可以解释使用 DWARF 将程序地址映射到行号的确切过程吗?

0 投票
3 回答
9480 浏览

gdb - 整个程序中库的调试符号中缺少行号,但不是单独的

在尝试使用 gdb 为使用 libtool 构建的包调试测试程序时,我看到了一个奇怪的问题。如果我运行libtool --mode=execute gdb .libs/libfoo.so并要求它列出某个函数list Bar::Baz的源代码,我会按预期获得源代码。如果我运行libtool --mode=execute gdb binary,我可以闯入Bar::Baz(),并在堆栈跟踪中查看它的参数,但我没有得到源文件或行号,如下所示:

list Bar::Baz同样,如果我在调试可执行文件时尝试,我会得到

我已经确认二进制文件与 链接-g,并且我可以列出它的main功能,所以我知道存在一些调试信息。

当我说 时info sources,我得到了构建库的文件的完整列表,以及正确的绝对路径。当我说 时info shared,我得到了目标文件的正确路径,列中有Yes一个Syms

任何进一步的想法可能会出现什么问题,以及如何解决它?


编辑 1: 意外地,我在objdump -g有问题的库上运行,并得到以下输出:

这令人惊讶,因为objdump -h(我试图运行的)列出了一堆.debug_*部分。该objdump手册也提出readelf -w了建议,这似乎打印了大量信息。不过,我需要查看它实际提供的功能。


编辑2:所以,readelf -w产生了一些启示。无论出于何种原因,共享对象文件似乎都不包含来自绝大多数 链接到它的任何对象的调试信息。根据 Makefile,实际将对象收集到共享库中的命令可能未通过-g,因此信息未正确传播。有趣的是,这在我们所有其他配置上都有效(具有完整的调试信息),包括 x86_64 上的相同编译器版本(相对于目前的 x86)。


编辑 3:实际上通过在 LDFLAGS 上添加了 -g 的修改后的 Makefile 进行了完全重建,并且没有任何区别。现在我很好,真的很困惑。

0 投票
1 回答
2501 浏览

ios - 用于发布版本的 dSYM 文件

资源是否.dSYM包含除 DWARF 信息之外的任何其他信息?我已经创建了一个应用程序的发布版本。现在,如果我dwarfdump在它上面运行,它说可执行文件没有 DWARF 信息(说它是“空的”),这是我所期望的。但是,如果我dsymutil在它上面运行,它会创建非空符号文件。这些是二进制文件,所以我不知道里面有什么。任何人都可以启发我吗?这些文件是否有查看者?

0 投票
1 回答
467 浏览

c++ - 用clang表示C++

我想知道 clang 使用哪些类来表示 C++(不是 C)源信息

我需要在 DWARF( http://en.wikipedia.org/wiki/DWARF )中有用的内部表示。例如,对于类型,相关信息可能是:这种类型的字节大小,字节对齐这种类型等

我已经下载了 LLVM + Clang。我查看了http://clang.llvm.org/docs/InternalsManual.html但没有找到我的答案,所以有人可以指导我,也许我错过了一些东西并告诉我必须在哪些课程中开始寻找这些数据?

0 投票
0 回答
667 浏览

compiler-construction - 更改 ELF 字节序数据格式

我正在尝试编辑一些软件以同时使用 Big Endian ELF/DWARF 文件和 Little Endian ELF/DWARF 文件。为此,我认为拥有相同数据的 Little ELF 文件和 Big ELF 文件是个好主意。我在编译器中使用一个简单的程序来创建一个 ELF 目标文件,但是目标文件总是按照我正在使用的芯片架构的字节序进行格式化。有没有办法在单个芯片上获得单个程序的两个字节顺序?

谢谢。

0 投票
1 回答
1441 浏览

c++ - LLVM 异常;如何放松

目前,我正在使用 CreateEntryBlockAlloca 将变量插入块范围的开头:

现在,我想为非 POD 类型添加 Allocas(这可能需要在退出时使用析构函数/清理函数)。但是,在退出范围块的末尾添加析构函数调用是不够的,因为不清楚如何在抛出常规 DWARF 异常时调用它们(为了这个参数的目的,假设异常是从调用仅抛出 POD 类型的 C++ 函数的调用点抛出,所以不,在我的情况下,无知是幸福,除非我更好地理解它们,否则我想远离内在的 llvm 异常)。

我在想可能是我可以在堆栈中有一个带有 Alloca 寄存器的偏移量的表,并让异常处理程序(在堆栈底部,在 JIT 函数的调用点)遍历表上的这些偏移量并适当地调用析构函数。

我不知道的是如何查询使用 CreateAlloca 创建的 Alloca 寄存器的偏移量。我怎样才能可靠地做到这一点?

另外,如果您认为有更好的方法可以实现这一点,请在llvm的路径上赐教

  • 技术评论:JIT 代码在boost::context中被调用,它只在 try catch 中调用 JIT 代码,并且在 catch 上什么也不做,它只是从上下文中退出并返回到主执行堆栈。这个想法是,如果我在主执行堆栈中处理展开,我调用的任何函数(例如,清理堆栈变量)都不会从终止的 JIT 上下文中覆盖那些相同的堆栈内容,因此它不会被破坏。希望我有足够的意义
0 投票
2 回答
25301 浏览

assembly - GAS:.cfi_def_cfa_offset 的解释

我想解释一下 GCC 生成的程序集中与 .cfi_def_cfa_offset 指令一起使用的值。我隐约知道 .cfi 指令涉及调用帧和堆栈展开,但我想更详细地解释一下为什么在编译以下 C 程序时 GCC 输出的程序集中使用值 16 和 8在我的 64 位 Ubuntu 机器上。

C程序:

我在源文件 test.c 上调用了 GCC,如下所示gcc -S -O3 test.c:我知道 -O3 启用非标准优化,但为了简洁起见,我想限制生成的程序集的大小。

生成的程序集:

为什么生成的程序集中的 .cfi_def_cfa_offset 指令使用值 16 和 8?另外,为什么数字 22 用于本地函数开始和函数结束标签?