In hotspot/perfparser I notice that we fail to find srcfile information via `dwarf_getsrc_die` for a given address. To reproduce, eu-addr2line can be compared to addr2line from binutils: ``` $ cat main.rs fn main() { println!("Hello, world!"); } $ rustc main.rs $ objdump -S ./main ... 00000000000227f0 <_ZN4core3fmt3num53_$LT$impl$u20$core..fmt..UpperHex$u20$for$u20$i32$GT$3fmt17hd6956218784a7031E>: 227f0: 48 81 ec 88 00 00 00 sub $0x88,%rsp 227f7: 48 89 f0 mov %rsi,%rax 227fa: 8b 0f mov (%rdi),%ecx 227fc: 4c 8d 84 24 88 00 00 lea 0x88(%rsp),%r8 22803: 00 22804: 45 31 c9 xor %r9d,%r9d 22807: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) ... $ addr2line -e ./main -a 227f0 0x00000000000227f0 /rustc/9fda7c2237db910e41d6a712e9a2139b352e558b//src/libcore/fmt/num.rs:142 $ eu-addr2line -e ./main -a 227f0 0x00000000000227f0 ??:0 ``` I have zero experience with rust and too little understanding of DWARF still to know what the exact reason here is. It would be great if elfutils could support rust here too like binutils does.
It might help if you could attach the binary. Locally (Fedora 31, rustc 1.38.0) I cannot replicate. Neither binutils addr2line, not elfutils eu-addr2line seem able to resolve addresses to source lines.
Created attachment 12080 [details] binary for reproduction here's the compressed binary as compiled with rustc 1.39.0 (4560ea788 2019-11-04) note that this one is compiled today, so the output is a bit different: ``` $ addr2line -f -i -C -e ./main -a 227f0 0x00000000000227f0 core::fmt::Arguments::new_v1 /rustc/4560ea788cb760f0a34127156c78e2552949f734//src/libcore/fmt/mod.rs:316 core::str::slice_error_fail /rustc/4560ea788cb760f0a34127156c78e2552949f734//src/libcore/str/mod.rs:2068 ```
(In reply to Mark Wielaard from comment #1) > It might help if you could attach the binary. Locally (Fedora 31, rustc > 1.38.0) I cannot replicate. Neither binutils addr2line, not elfutils > eu-addr2line seem able to resolve addresses to source lines. Note that rpmbuild strips Rust's rlibs (static archives), so you won't have any debuginfo for pre-compiled code from the standard library. You should still be able to resolve the user's own code though, as well as generic std code that gets monomorphized in the user's compilation. $ bat main.rs ───────┬────────────────────────────────── │ File: main.rs ───────┼────────────────────────────────── 1 │ fn main() { 2 │ println!("Hello, world!"); 3 │ } ───────┴────────────────────────────────── $ rustc -g main.rs $ nm main | grep main U __libc_start_main@@GLIBC_2.2.5 00000000000053d0 T main 0000000000005390 t _ZN4main4main17h6b07ac6c6f06cdd6E $ addr2line -e main 5390 /tmp/hello/src/main.rs:1 $ eu-addr2line -e main 5390 ??:0
I can also reproduce this with Clang (clang-9.0.0-1.fc31.x86_64), so it seems to be a more general problem with LLVM as the producer. $ bat main.c ───────┬────────────────────────────────── │ File: main.c ───────┼────────────────────────────────── 1 │ #include <stdio.h> 2 │ int main() { 3 │ printf("Hello, world!\n"); 4 │ return 0; 5 │ } ───────┴────────────────────────────────── $ clang -g main.c -o main $ nm main | grep main U __libc_start_main@@GLIBC_2.2.5 0000000000401130 T main $ addr2line -e main 401130 /tmp/hello/src/main.c:2 $ eu-addr2line -e main 401130 ??:0 When compiled with GCC, eu-addr2line resolves it fine.
I suspect this is the same as https://sourceware.org/bugzilla/show_bug.cgi?id=22288 If so then rustc -Cllvm-args=-generate-arange-section should resolve it.
Aha, I thought this was familiar. I guess I should try to implement that aranges change in rustc after all. However, I think elfutils should probably still try to deal without aranges, on par with binutils.
hmm but in perfparser we have a workaround for missing aranges... I'll have to dig into this to see why it doesn't work here.
(In reply to Milian Wolff from comment #7) > hmm but in perfparser we have a workaround for missing aranges... I'll have > to dig into this to see why it doesn't work here. You also mention it is an issue with dwarf_getsrc_die in the subject. Which would indicate that it is some other issue, because when you call dwarf_getsrc_die you already would have found the DIE (by address). So maybe it is something else in your case? BTW. I do agree it would be nice if libdw handled missing debug_aranges. The problem is simply that you cannot know the difference between missing and not covered. Which means that for any address lookup that doesn't match an arange you would have to do some fallback lookup, which could be expensive. So still pondering how to handle this without penalizing debug files that do have correct and complete aranges (maybe we could just handle the case where there are just no .debug_aranges at all, and only then make some fallback code kick in?)