[英]how to get line numbers same as lldb using atos/addr2line/llvm-symbolizer/lldb image lookup --address
I want to programmatically convert backtrace stack addresses (eg obtained from backtrace_symbols/libunwind) to file:line:column.我想以编程方式将回溯堆栈地址(例如从 backtrace_symbols/libunwind 获得)转换为 file:line:column。 I'm on OSX but doubt this makes a difference.
我在 OSX 上,但怀疑这有什么不同。
All of these give wrong line number (line 11) for the call to fun1():所有这些都为调用 fun1() 提供了错误的行号(第 11 行):
image lookup --address
using lldb's pc addresses in bt image lookup --address
使用 lldb 在 bt 中的 pc 地址lldb bt
itself gives correct file:line:column, (line 7) as shown below. lldb
bt
本身给出正确的文件:行:列,(第 7 行),如下所示。
How do I programmatically get the correct stack address such that, when using atos/addr2line/llvm-symbolizer/image lookup --address, it would resolve to the correct line number?我如何以编程方式获取正确的堆栈地址,以便在使用 atos/addr2line/llvm-symbolizer/image lookup --address 时,它会解析为正确的行号? lldb
bt
is doing it correctly, so there must be a way to do it. lldb
bt
做对了,所以一定有办法做到。 Note that if I use backtrace_symbols
or libunwind
(subtracted from info.dli_saddr
after calling dladdr
), I'd end up with the same address 0x0000000100000f74
as shown in lldb bt that points to the wrong line number 11需要注意的是,如果我使用
backtrace_symbols
或libunwind
(相减info.dli_saddr
调用后dladdr
),我结束了同一个地址0x0000000100000f74
如图LLDB BT是指向错误的行数11
Note: in .lldbinit, if I add settings set frame-format frame start-addr:${line.start-addr}\\n
it will show the correct address (ie resolve to 0x0000000100000f6f instead of 0x0000000100000f74, which will resolve to the correct line 7).注意:在 .lldbinit 中,如果我添加
settings set frame-format frame start-addr:${line.start-addr}\\n
它将显示正确的地址(即解析为 0x0000000100000f6f 而不是 0x0000000100000f74,它将解析为正确的第 7 行)。 However, how do I programmatically generate start-addr from ac program without calling spawning a call to lldb -p $pid
(calling lldb has other issues, eg overhead compared to llvm-symbolizer, and in fact can hang forever even with -batch
).但是,如何以编程方式从 ac 程序生成 start-addr 而不调用产生对
lldb -p $pid
调用(调用 lldb 有其他问题,例如与 llvm-symbolizer 相比的开销,实际上即使使用-batch
也可以永远挂起) .
clang -g -o /tmp/z04 test_D20191123T162239.c
test_D20191123T162239.c: test_D20191123T162239.c:
void fun1(){
}
void fun1_aux(){
int a = 0;
fun1(); // line 7
mylabel:
if(1){
a++; // line 11
}
}
int main(int argc, char *argv[]) {
fun1_aux();
return 0;
}
lldb /tmp/z04
(lldb) target create "/tmp/z04"
Current executable set to '/tmp/z04' (x86_64).
(lldb) b fun1
Breakpoint 1: where = z04`fun1 + 4 at test_D20191123T162239.c:2:1, address = 0x0000000100000f54
(lldb) r
Process 7258 launched: '/tmp/z04' (x86_64)
Process 7258 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000f54 z04 fun1 + 4 at test_D20191123T162239.c:2:1
1 void fun1(){
-> 2 }
3
4 void fun1_aux(){
5 int a = 0;
6
7 fun1();
Target 0: (z04) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000100000f54 z04 fun1 + 4 at test_D20191123T162239.c:2:1
frame #1: 0x0000000100000f74 z04 fun1_aux + 20 at test_D20191123T162239.c:7:3
frame #2: 0x0000000100000fab z04 main(argc=1, argv=0x00007ffeefbfb748) + 27 at test_D20191123T162239.c:16:3
frame #3: 0x00007fff71c182e5 libdyld.dylib start + 1
frame #4: 0x00007fff71c182e5 libdyld.dylib start + 1
(lldb)
(lldb) image lookup --address 0x0000000100000f74
Address: z04[0x0000000100000f74] (z04.__TEXT.__text + 36)
Summary: z04`fun1_aux + 20 at test_D20191123T162239.c:11:8
echo 0x0000000100000f74 | llvm-symbolizer -obj=/tmp/z04
fun1_aux
test_D20191123T162239.c:11:8
atos -o /tmp/z04 0x0000000100000f74
fun1_aux (in z04) (test_D20191123T162239.c:11)
likewise with addr2line
同样使用
addr2line
It's easier to understand if you look at the disassembly for fun1_aux
-- you'll see a CALLQ instruction to fun1
, followed by something like a mov %rax, $rbp-16
or something like that, the first instruction of your a++
line.如果您查看
fun1_aux
的反汇编会更容易理解——您会看到一条 CALLQ 指令到fun1
,然后是类似mov %rax, $rbp-16
或类似内容的指令,即a++
行的第一条指令。 When you have called fun1
, the return address is the instruction that will be executed when fun1
exits, the mov %rax, $rbp-16
or whatever.当您调用
fun1
,返回地址是当fun1
退出时将执行的指令、 mov %rax, $rbp-16
或其他任何指令。
This isn't intuitively how most people think of the computer working -- they expect to look at frame 1, fun1_aux
, and see the "current pc value" be the CALLQ, because the call is executing .这不是大多数人对计算机工作的直观看法——他们希望查看第 1 帧
fun1_aux
并看到“当前 pc 值”是 CALLQ,因为调用正在执行。 But of course, that's not correct, the call instruction has completed, and the saved pc is going to point to the next instruction.但是当然,那是不正确的,调用指令已经完成,保存的pc将指向下一条指令。
In cases like this, the next instruction is part of the next source line, so it's a little extra confusing.在这种情况下,下一条指令是下一条源代码行的一部分,因此有点令人困惑。 Even better is if you have a function that calls a "noreturn" function like
abort()
-- the final instruction in the function will be a CALLQ, and if you look at the return address instruction, it may point to the next function .更好的是,如果您有一个函数调用像
abort()
这样的“noreturn”函数——函数中的最后一条指令将是 CALLQ,如果您查看返回地址指令,它可能指向下一个函数。
So when lldb is symbolicating stack frames above frame #0, it knows to do a symbol lookup with saved_pc - 1
to move the address back into the CALLQ instruction.因此,当 lldb 对帧 #0 上方的堆栈帧进行符号化时,它知道使用
saved_pc - 1
进行符号查找以将地址移回 CALLQ 指令。 That's not a valid address, so it should never show you saved_pc - 1
, but it should do symbol / file & line lookups based on it.这不是一个有效的地址,所以它永远不应该向你显示
saved_pc - 1
,但它应该基于它进行符号/文件和行查找。
You can get the same effect for your manual symbolication by doing the same thing.通过执行相同的操作,您可以为手动符号化获得相同的效果。 The one caveat is if you have an asynchronous interrupt (
_sigtramp
on macOS), the frame above _sigtramp
should not have its saved pc value decremented.一个需要注意的是,如果你有一个异步中断(
_sigtramp
在MacOS),上述框架_sigtramp
不应该其保存的PC值递减。 You could be executing the first instruction of a function when the signal is received, and decrementing it would put you in the previous function which would be very confusing.当接收到信号时,您可能正在执行函数的第一条指令,并且递减它会使您进入前一个函数,这会非常混乱。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.