-
Notifications
You must be signed in to change notification settings - Fork 12.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
Add libbacktrace support for Apple platforms #43422
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @nikomatsakis (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
This is great! Not having filenames / line-numbers on mac os X is so sad. This PR looks good to me, but I think it's missing a few things. In particular, there is no testing! Poking around in the codebase, it appears that our existing Truth is though that I am not an expert on this stuff in general. cc @michaelwoerister and @alexcrichton, both of whom seem like likely candidates to give good suggestions for other tests and things to re-enable. |
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.
Well, this seems to be passing all the existing tests, so I am happy with it, but I'd like to get the advice of @alexcrichton or someone else on how to handle the patch to libbacktrace.
if cfg!(any(target_os = "macos", | ||
target_os = "ios", | ||
target_os = "android", | ||
if cfg!(any(target_os = "android", |
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.
👍
@@ -0,0 +1,1414 @@ | |||
/* macho.c -- Get debug data from an Mach-O file for backtraces. |
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.
Can you maybe insert a link to the pending patch in libbacktrace itself?
Clearly we're not in a good position to review this independently, but it'd be nice to be able to place this in the context of that project.
@JohnColanduoni are the upstream changes located at ianlancetaylor/libbacktrace#2? If that's the case, do you know if that's "close to landing"? |
pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> { | ||
Err(io::Error::new(io::ErrorKind::Other, "Not implemented")) | ||
} | ||
|
||
#[cfg(any(target_os = "macos", target_os = "ios"))] | ||
pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> { |
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 looks almost equivalent to std::env::current_exe()
, could you elaborate a bit on why that couldn't be used here?
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.
@alexcrichton the PR description talks about that:
I've avoided calling that function to prevent having to play with the type of the returned filename, since the existing version calls for a null-terminated Vec<c_char> instead of a Vec with no null termination.
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.
Ah yes indeed! @JohnColanduoni would you be willing to change this to use std::env::current_exe
? I believe the return value can then be converted to a Vec
of the appropriate type to nul terminate (or just create a CString
with) and such.
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.
@alexcrichton Sorry I missed your message, I've made the requested changes.
@alexcrichton I made the changes Ian requested about two months ago but I don't think he's had time to look at them. |
@JohnColanduoni ok that's fine, just wanted to make sure everything was linked up correctly! I think it's ok to land this ahead of it landing upstream if it's taking awhile. Out of curiosity, how confident are you in this implementation? Historically we've had a number of segfaults due to libbacktrace bugs, which in turn could unfortunately translate to security vulnerabilities for Rust programs if we're not careful! Do know know if this has been thoroughly tested and such? |
@alexcrichton I'm fairly confident, I coded it under the assumption that the input may be malformed and the Mach-O header and symbol table formats are pretty simple. The more sophisticated DWARF data is handled by the same code that handles the ELF/PE versions. |
@rust-lang/libs any thoughts on this? I'm a little worried about the maintenance burden we're bringing on ourselves as downstream consumers of libbacktrace for this, but this is a highly desired feature to have filename/line number working on OSX when possible. |
We should land it IMO. |
@bors: r+ Ok Thanks @JohnColanduoni! Let's see how this goes. |
📌 Commit 5991ab7 has been approved by |
⌛ Testing commit 5991ab7 with merge d5ca0e6da9ce5f933a1c8fb0d0f9d985cad0a01a... |
💔 Test failed - status-travis |
Failed to build
Probably just change this. diff --git a/src/libbacktrace/config.sub b/src/libbacktrace/config.sub
index da6d1b6826..f6cac20b58 100644
--- a/src/libbacktrace/config.sub
+++ b/src/libbacktrace/config.sub
@@ -1392,7 +1392,7 @@ case $os in
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -ios* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ |
☔ The latest upstream changes (presumably #43635) made this pull request unmergeable. Please resolve the merge conflicts. |
Would be a great early Christmas present to get this working! |
Changing |
@JohnColanduoni just a friendly ping to keep this on your radar! I can see there are some merge conflicts. |
I'm going to close this to keep the PR queue clean, but we would love to get this in so please feel free to make a new PR, or ping me once resolving the conflicts and I'll reopen! |
Add libbacktrace support for Apple platforms (resubmitted) Resubmitting #43422 rebased on the current master (cc @JohnColanduoni). I have added an additional commit to fallback to `dladdr`-based `resolve_symbol` if `libbacktrace` returns `None`, otherwise the stack trace will be full of `<unknown>` when you forget to pass the `-g` flag (actually it seems — at least on macOS — the `dladdr` symbol is more accurate than the `libbacktrace` one).
This adds support for Mach-O files (used for binaries on macOS and iOS) to libbacktrace, and enables libbacktrace on those platforms. Unlike the current
dladdr
based method used on these platforms, it provides filenames and line numbers (fixing #24346 for Apple targets).These changes to libbacktrace are on their way upstream, but have been stalled for a number of months so I've put together a PR that adds them directly to Rust's fork.
libbacktrace's internal detection of the executable path that was relied on for other platforms does not work for macOS, so I've replaced the stub
backtrace::gnu::get_executable_filename
with a working version based on_NSGetExecutablePath
(the same method used to implementstd::env::current_exe
). I've avoided calling that function to prevent having to play with the type of the returned filename, since the existing version calls for a null-terminatedVec<c_char>
instead of aVec<u8>
with no null termination.