-
Notifications
You must be signed in to change notification settings - Fork 17
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
Read ELF build ids directly from the target process. #112
Conversation
Closes rust-minidump#71. A few things to consider: * Since we read from the process memory, the process must be in ptrace-stop (see `test_file_id`). This changes when the build ids can be read. Previously they could be read without the process being stopped if the mapped files still existed (and were hopefully the same that the process was using). * The previous implementation made some mutations to deleted mapping names (removing the ` (deleted)` suffix). We need to decide whether we still want/need this behavior. In the meantime I commented out a failing test assertion.
Maybe |
This test needed to be disabled due to permissions issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've left a small comment but noticed a bigger issue. On my Gentoo machine there's a lot of failures and I'm not 100% sure what's going on, however what I see consistently is the following:
- We call
PtraceDumper::elf_identifier_for_mapping()
on/usr/lib/gcc/x86_64-pc-linux-gnu/13/libgcc_s.so.1
which in turns callsbuild_id_reader::read_build_id()
build_id_reader::read_build_id()
triesElfBuildIdReader::read_from_program_headers()
which fails, because this file doesn't have a build ID so we can't find the notebuild_id_reader::read_build_id()
proceeds withElfBuildIdReader::read_from_section()
and here things go south.read_section_headers()
callself::SectionHeader::parse()
with an offset of 0 which causes it to return an empty array, see here- We attempt to execute this on an empty array and the test fails
let strtab_section_header = §ion_headers[self.header.e_shstrndx as usize];
One very crude way of fixing this is to add 1 byte in front of the slice containing the section headers, so that goblin really parses them instead of returning the empty vector. That being said we should still handle the case where self.header.e_shstrndx
ends up being out-of-bounds, even though it might have masked this failure.
Oh no! Looks like we could just use |
It seems like some more unit tests to cover these cases are necessary, though it will be a bit contrived to e.g. create binaries with only a build id in them (to not waste space in the repo). But I'll try to add something. |
I've added tests (with a small, handcrafted ELF file). I made the ELF file by making a bunch of modifications to https://github.com/tchajed/minimal-elf; I'm wondering whether I should include the code that created it in the repo? I sadly just realized that goblin does implement |
After a bit of wrangling with the
Given that I don't know a way to recover the text section from the program headers alone, and that the failure is triggered by an executable that doesn't have a build ID in the first place I think we can let it slide. We'll never encounter this in practice within Firefox, because the program headers of our various executables will always include the build ID. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is OK as it is.
Closes #71.
A few things to consider:
test_file_id
). This changes when the build ids can be read. Previously they could be read without the process being stopped if the mapped files still existed (and were hopefully the same that the process was using).(deleted)
suffix). We need to decide whether we still want/need this behavior. In the meantime I commented out a failing test assertion.