-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/link: .debug_pubnames and .debug_pubtypes not following DWARF4 spec #30573
Comments
@heschik @aarzilli @aclements |
This is my faul, I wrote the CL that distrubutes variables among CUs and exposes the bug. I'll write a fix for it. |
PS. the bug is in cmd/link |
I worked with Jason on this issue and I agree that the DWARF is incorrect. One interesting thing to note is that both |
Change https://golang.org/cl/165337 mentions this issue: |
I also have a different proposal: let's remove debug_pubnames/debug_pubtypes. They are entirely optional (DWARFv4, section 6.1, page 105), anything that can be done with them can be done without them and pubnames has been wrong for a long time. It's supposed to have entries for public functions but it hasn't since 1.8 (I think) when DWARF generation for functions was moved to the compiler. It'll save some linker time and disk space at the expense of slower global variable lookup in some debuggers (assuming gdb and lldb don't compensate for its absence). |
I currently have some code that makes use of the debug_pubtypes section, so speaking personally it would be nice if it stuck around :) |
For the moment, if we've got it, it should at least follow the spec IMO. I'll take a look at the CL. I think @aclements would need to make a call on whether to remove them. Austin? |
Given that these sections are 0.6% of the cmd/go binary, I'm not too worried about the space (though perhaps there is a broader "death by a thousand cuts" issue). I'm more worried about them being incomplete. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I ran dwarfdump on the compiled binary of the following sample code:
https://play.golang.org/p/CVBXqakTEye
What did you expect to see?
A full normal dwarfdump output, including the .debug_pubnames and .debug_pubtypes sections.
What did you see instead?
Dwarfdump exits early instead, emitting a failure.
The following is the tail end of the dwarfdump output before it fails. The failure occurs while processing the first .debug_pubnames entry found in the second CU:
More details on underlying cause
It was the libdwarf maintainer, David Anderson, who determined the underlying issue. In summary, the entries emitted in the .debug_pubnames and the .debug_pubtypes sections contain the global die offset for the entry, and not the offset from the start of the CU it is found in, as specified in section 6.1.1 of the DWARF4 spec.
Also as an interesting note, this issue happens to not be noticeable on Go 1.11, as all of the pubtypes and pubnames entries were found in the first CU, so the global offsets and the offset from their CU were the same.
The following snippet from running llvm-dwarfdump shows the first and second CU entries from the .debug_pubnames output:
The error message in the earlier dwarfdump output above shows it attempting to access the DIE at global offset 0x1a12, and finding that location does not contain a valid DIE entry. This is because dwarfdump is taking the offset of 0x00000e6e and adding it to the CU offset of 0x00000ba4 (listed in the llvm-dwardump) to obtain what it believes is the global offset of 0x1a12. However the offset of 0x00000e6e is already the global offset.
This is seen here by running dwarfdump -G -M -i and finding the .debug_info entry for internal/bytealg.MaxLen.
The global offset is 0x0e6e, and its offset within the CU is 0x02ca. Subtracting 0x02ca from 0xe6e gives 0x0ba4, which matches the offset of the CU itself shown in the llvm-dwardump output. So the offset that should be appearing in the pubname section for internal/bytealg.MaxLen should be 0x02ca, which is its offset from the start of the CU.
Also, as shown in this hexdump snippit, the global offset of 0x0e6e is coming from the binary itself, the 4 bytes starting at byte position 00193fc2, which precedes the string "internal/bytealg.MaxLen".
The text was updated successfully, but these errors were encountered: