rustc_codegen_cranelift
rustc_codegen_cranelift copied to clipboard
DWARF support
- [x] Unmangled symbols names (#1470)
- [ ] Arguments and locals
- [x] Statics (#1472)
- [ ] Types
- [x] Line info (#291)
- [ ] Inlining information (long term)
- [x] Backtrace information (#982)
- [ ] Unwinding information (long term)
Edit: add unwinding information Edit2: state which things are for the long term Edit3: gimli-rs/gimli#340 has been merged Edit4: m4b/faerie#51 has been merged and CraneStation/cranelift#426 is not necessary anymore I believe.
Does this cover eh_frame too?
Added
From https://github.com/m4b/faerie/pull/51#issuecomment-443930827 by @philipc:
https://github.com/philipc/rustc_codegen_cranelift/tree/debuginfo https://github.com/philipc/cranelift/tree/debug
Both still WIP. The rustc support will be better once it's using more of rustc_codegen_ssa (eg it has set_debug_loc() calls in all the right places). I'm currently working on .debug_line support in gimli.
I don't see the .debug_info contents. :(
(please note that I had to rebase both branches to get it working with the latest nightly)
$ llvm-dwarfdump-3.8 target/out/mini_core_hello_world
target/out/mini_core_hello_world: file format ELF64-x86-64
.debug_abbrev contents:
Abbrev table for offset: 0x00000000
[1] DW_TAG_compile_unit DW_CHILDREN_yes
DW_AT_producer DW_FORM_strp
DW_AT_language DW_FORM_udata
DW_AT_name DW_FORM_strp
DW_AT_comp_dir DW_FORM_strp
[2] DW_TAG_subprogram DW_CHILDREN_no
DW_AT_linkage_name DW_FORM_strp
DW_AT_decl_file DW_FORM_strp
DW_AT_decl_line DW_FORM_udata
DW_AT_decl_column DW_FORM_udata
Abbrev table for offset: 0x0000001b
[1] DW_TAG_compile_unit DW_CHILDREN_yes
DW_AT_producer DW_FORM_strp
DW_AT_language DW_FORM_udata
DW_AT_name DW_FORM_strp
DW_AT_comp_dir DW_FORM_strp
[2] DW_TAG_subprogram DW_CHILDREN_no
DW_AT_linkage_name DW_FORM_strp
DW_AT_decl_file DW_FORM_strp
DW_AT_decl_line DW_FORM_udata
DW_AT_decl_column DW_FORM_udata
.debug_abbrev.dwo contents:
< EMPTY >
.debug_info contents:
.debug_loc contents:
.debug_loc.dwo contents:
.debug_frame contents:
.debug_macinfo contents:
.debug_aranges contents:
.debug_line contents:
.debug_cu_index contents:
.debug_tu_index contents:
.debug_line.dwo contents:
.debug_str contents:
0x00000000: "example/mini_core_hello_world.rs"
0x00000021: "/home/bjorn/Documenten/rustc_codegen_cranelift"
0x00000050: "cranelift (rustc version unknown version)"
0x0000007a: "_ZN21mini_core_hello_world4main17he1655d58f9d91204E"
0x000000ae: "_ZN68_$LT$mini_core_hello_world..NoisyDrop$u20$as$u20$mini_core..Drop$GT$4drop17h6f94045255c03089E"
0x00000111: "_ZN63_$LT$$LP$$RP$$u20$as$u20$mini_core_hello_world..Termination$GT$6report17hdb0778df210e78ccE"
0x00000171: "_ZN9mini_core13drop_in_place17hce2f1c802ab2620fE"
0x000001a2: "/home/bjorn/Documenten/rustc_codegen_cranelift/example/mini_core.rs"
0x000001e6: "_ZN21mini_core_hello_world5start17h1e715bf6fab28115E"
0x0000021b: "_ZN9mini_core13drop_in_place17hd9450b03d573a12fE"
0x0000024c: "_ZN73_$LT$mini_core_hello_world..NoisyDropInner$u20$as$u20$mini_core..Drop$GT$4drop17h47d84ca54e8a334aE"
0x000002b4: "_ZN9mini_core13drop_in_place17h916a3813cccd8138E"
0x000002e5: "_ZN76_$LT$$RF$$u27$static$u20$str$u20$as$u20$mini_core_hello_world..SomeTrait$GT$11object_safe17ha78f10b266d14c40E"
0x00000358: "_ZN9mini_core13drop_in_place17h0dfa83ab1d2ac08dE"
0x00000389: "example/mini_core.rs"
0x0000039e: "/home/bjorn/Documenten/rustc_codegen_cranelift"
0x000003cd: "cranelift (rustc version unknown version)"
0x000003f7: "_ZN9mini_core8allocate17h122bb7e874c2cf63E"
0x00000422: "_ZN37_$LT$u8$u20$as$u20$mini_core..Add$GT$3add17h2ed4592d072eae4dE"
0x00000465: "_ZN68_$LT$$RF$$u27$a$u20$bool$u20$as$u20$mini_core..BitOr$LT$bool$GT$$GT$5bitor17hbdb95c272ef985e2E"
0x000004c9: "_ZN40_$LT$usize$u20$as$u20$mini_core..Sub$GT$3sub17h5e441af28e85913cE"
0x0000050f: "_ZN43_$LT$u8$u20$as$u20$mini_core..PartialEq$GT$2eq17h19e3d34341b7ef63E"
0x00000557: "_ZN37_$LT$u8$u20$as$u20$mini_core..Mul$GT$3mul17h1b0786eb335e6b00E"
0x0000059a: "_ZN41_$LT$bool$u20$as$u20$mini_core..BitOr$GT$5bitor17h7c5a454fe7ec849bE"
0x000005e3: "_ZN45_$LT$char$u20$as$u20$mini_core..PartialEq$GT$2ne17h3bbde2eaedbb9611E"
0x0000062d: "_ZN39_$LT$bool$u20$as$u20$mini_core..Not$GT$3not17hd55c09678b9ff6b0E"
0x00000672: "_ZN40_$LT$isize$u20$as$u20$mini_core..Neg$GT$3neg17h61958dbcef5ebc0fE"
0x000006b8: "_ZN45_$LT$char$u20$as$u20$mini_core..PartialEq$GT$2eq17hdae5677cbecc8595E"
0x00000702: "_ZN43_$LT$u8$u20$as$u20$mini_core..PartialEq$GT$2ne17hc2dba50b5506e1e4E"
0x0000074a: "rust_eh_personality"
0x0000075e: "_ZN9mini_core5panic17h1b8c87c5633941c5E"
.debug_ranges contents:
.debug_pubnames contents:
.debug_pubtypes contents:
.debug_gnu_pubnames contents:
.debug_gnu_pubtypes contents:
.apple_names contents:
.apple_types contents:
.apple_namespaces contents:
.apple_objc contents:
$ readelf --sections target/out/mini_core_hello_world
There are 31 section headers, starting at offset 0x51a8:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000000238 00000238
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.ABI-tag NOTE 0000000000000254 00000254
0000000000000020 0000000000000000 A 0 0 4
[ 3] .note.gnu.build-i NOTE 0000000000000274 00000274
0000000000000024 0000000000000000 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000000298 00000298
000000000000001c 0000000000000000 A 5 0 8
[ 5] .dynsym DYNSYM 00000000000002b8 000002b8
00000000000000c0 0000000000000018 A 6 1 8
[ 6] .dynstr STRTAB 0000000000000378 00000378
0000000000000096 0000000000000000 A 0 0 1
[ 7] .gnu.version VERSYM 000000000000040e 0000040e
0000000000000010 0000000000000002 A 5 0 2
[ 8] .gnu.version_r VERNEED 0000000000000420 00000420
0000000000000020 0000000000000000 A 6 1 8
[ 9] .rela.dyn RELA 0000000000000440 00000440
00000000000003a8 0000000000000018 A 5 0 8
[10] .init PROGBITS 00000000000007e8 000007e8
0000000000000017 0000000000000000 AX 0 0 4
[11] .plt PROGBITS 0000000000000800 00000800
0000000000000010 0000000000000010 AX 0 0 16
[12] .plt.got PROGBITS 0000000000000810 00000810
0000000000000010 0000000000000000 AX 0 0 8
[13] .text PROGBITS 0000000000000820 00000820
00000000000014dd 0000000000000000 AX 0 0 16
[14] .fini PROGBITS 0000000000001d00 00001d00
0000000000000009 0000000000000000 AX 0 0 4
[15] .eh_frame_hdr PROGBITS 0000000000001d0c 00001d0c
0000000000000034 0000000000000000 A 0 0 4
[16] .eh_frame PROGBITS 0000000000001d40 00001d40
00000000000000ec 0000000000000000 A 0 0 8
[17] .init_array INIT_ARRAY 0000000000202dd8 00002dd8
0000000000000008 0000000000000008 WA 0 0 8
[18] .fini_array FINI_ARRAY 0000000000202de0 00002de0
0000000000000008 0000000000000008 WA 0 0 8
[19] .jcr PROGBITS 0000000000202de8 00002de8
0000000000000008 0000000000000000 WA 0 0 8
[20] .dynamic DYNAMIC 0000000000202df0 00002df0
00000000000001c0 0000000000000010 WA 6 0 8
[21] .got PROGBITS 0000000000202fb0 00002fb0
0000000000000050 0000000000000008 WA 0 0 8
[22] .data PROGBITS 0000000000203000 00003000
0000000000000530 0000000000000000 WA 0 0 8
[23] .bss NOBITS 0000000000203530 00003530
0000000000000008 0000000000000000 WA 0 0 1
[24] .comment PROGBITS 0000000000000000 00003530
000000000000002d 0000000000000001 MS 0 0 1
[25] .debug_info PROGBITS 0000000000000000 0000355d
000000000000014c 0000000000000000 0 0 1
[26] .debug_abbrev PROGBITS 0000000000000000 000036a9
0000000000000036 0000000000000000 0 0 1
[27] .debug_str PROGBITS 0000000000000000 000036df
0000000000000786 0000000000000000 0 0 1
[28] .symtab SYMTAB 0000000000000000 00003e68
0000000000000bb8 0000000000000018 29 92 8
[29] .strtab STRTAB 0000000000000000 00004a20
0000000000000668 0000000000000000 0 0 1
[30] .shstrtab STRTAB 0000000000000000 00005088
000000000000011b 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
l (large), p (processor specific)
$ readelf --hex-dump=.debug_info target/out/mini_core_hello_world
Hex dump of section '.debug_info':
0x00000000 89000000 05000108 00000000 01500000 .............P..
0x00000010 001c0000 00002100 0000027a 00000000 ......!....z....
0x00000020 00000076 0002ae00 00000000 00003e04 ...v..........>.
0x00000030 02110100 00000000 00220402 71010000 ........."..q...
0x00000040 a2010000 ee010002 e6010000 00000000 ................
0x00000050 5400021b 020000a2 010000ee 0100024c T..............L
0x00000060 02000000 00000046 0402b402 0000a201 .......F........
0x00000070 0000ee01 0002e502 00000000 00002f04 ............../.
0x00000080 02580300 00a20100 00ee0100 00bb0000 .X..............
0x00000090 00050001 081b0000 0001cd03 00001c89 ................
0x000000a0 0300009e 03000002 f7030000 89030000 ................
0x000000b0 fc010002 22040000 89030000 6c040265 ....".......l..e
0x000000c0 04000089 03000093 010402c9 04000089 ................
0x000000d0 0300007b 04020f05 00008903 00009f01 ...{............
0x000000e0 04025705 00008903 00005d04 029a0500 ..W.......].....
0x000000f0 00890300 008b0104 02e30500 00890300 ................
0x00000100 00ab0104 022d0600 00890300 004d0402 .....-.......M..
0x00000110 72060000 89030000 c3010402 b8060000 r...............
0x00000120 89030000 a8010402 02070000 89030000 ................
0x00000130 a2010402 4a070000 89030000 e8010002 ....J...........
0x00000140 5e070000 89030000 e1010000 ^...........
Posting here, because I think this is a more appropriate place to continue this conversation.
I'll look into it later today, but maybe you need to change the DWARF version to 4. I've been using gimli's dwarfdump, I'll try llvm-dwarfdump later.
Thanks. Using version 4 fixes it.
I rebased @philipc's debuginfo branch and extended it a bit.
It is currently blocked on CraneStation/cranelift#651 (merged) and m4b/faerie#59 (merged)
_argc=<optimized out> here confuses me, because I provided DW_AT_location.
~/Documents/rustc_codegen_cranelift(philipc_debuginfo_updated*) » gdb target/out/mini_core_hello_world
[...]
(gdb) break main
Breakpoint 1 at 0x1db0
(gdb) run
Starting program: /home/bjorn/Documents/rustc_codegen_cranelift/target/out/mini_core_hello_world
Breakpoint 1, 0x0000000008001db0 in main ()
(gdb) si
0x0000000008001db2 in main ()
[...]
0x0000000008001dc5 in main ()
(gdb) si
0x0000000008000a00 in mini_core_hello_world::start::h1e715bf6fab28115 (main=..., _argc=<optimized out>, _argv=...)
Looks like gdb ignores DW_TAG_formal_parameter if a DW_TAG_variable shadows it, since deleting the DW_TAG_variable gives:
Breakpoint 1, 0x0000555555555b70 in mini_core_hello_world::start::h1e715bf6fab28115 (main=..., _argc=1, _argv=...)
This duplication of arguments as variables is unnecessary and should be avoided (see https://github.com/rust-lang/rust/pull/45380).
Thanks. I renamed the DW_TAG_formal_parameter for now.
Note to self:
DW_AT_variable_parameterforDW_TAG_formal_parameter.debug_locfor changing variable locations- http://dwarfstd.org/doc/DWARF4.pdf
DW_AT_stmt_listonDW_TAG_compile_unitis needed for line info.- According https://llvm.org/devmtg/2014-10/Slides/Christopher-DebugInfoTutorial.pdf omitting
is_stmtcauses gdb to do strange things. - https://events.static.linuxfound.org/images/stories/pdf/lfcs2012_eager.pdf
- http://dwarfstd.org/doc/Debugging%20using%20DWARF-2012.pdf
@philipc could you advise me some other sources about DWARF information than the spec?
Most of my information comes from:
- DWARF spec
- inspecting binaries using dwarfdump/llvm-dwarfdump/readelf
- reading LLVM/gdb source code
If you have a specific question I can try to answer.
Thanks, I have no questions at the moment though.
#291 has been merged! :tada:
Thanks for your effort on this! Im guessing the Cranelift backend won't optimise away variables like the current LLVM compiler does?
Is this at a stage to try out debugging?
Cranelift can optimize SSA variables (those storing primitive values and not having their address taken) away (though not sure if it also does this when opt_level is set to none, like cg_clif currently does) when there is no user. When compiling in release mode, some stack slot accesses turn into SSA variables. I haven't yet implemented correct debuginfo generation for this. In all other cases variables are not optimized away.
Currently debuginfo generation for locals is disabled, as there are still a lot of unhandled types and storage locations.
Lineinfo is supported, though with some small issues. For example when returning from a function, the current line temporarily jumps to the start of the function (https://github.com/bytecodealliance/cranelift/issues/1172). Also single stepping goes into macros. It is usable though.
a49416da6ddcbcbd40f7aadb06b71d77c23e8220 will remove stub local debuginfo implementation. It isn't actually wired up and temporarily removing it will make changes to the debuginfo generation code much simpler. I will reintroduce this code at a later point.
In fee1204ffa7d5c989a2cb76d6b3bb8daa51af811...4f0cde1e51dbfb20a2260a0fc83a5c1359b4dc9d I fixed debug info generation for arrays, implemented it for tuples and define return types for functions.