-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Expose debug-id via API, or include in stacktrace #43274
Comments
Just a note, I have started on this, but it's requiring a bit of rework on how we do an end-run around the embedder API for extra information that only exists for precompiled snapshots, and I still need to check into how to handle the build ID generation for assembly snapshots. Will update here if I run into any blockers (none expected at the moment though). |
CL 163207 is now under review. That CL adds build IDs to non-symbolic stack traces for ELF-compiled snapshots. Having build IDs be consistent between assembly snapshots and their separate ELF debugging information (by generating them ourselves for assembly output) remains to be done. |
Since we've run out of room for more fields in the Image object header on 64-bit architectures, the serializer instead creates an ImageHeader object for precompiled snapshots that is placed at the start of text segments. The new ImageHeader object contains the following information: * The offset of the BSS segment from the text segment, previously stored in the Image object header. * The relocated address of the text segment in the dynamic shared object. Due to restrictions when generating assembly snapshots, this field is only set for ELF snapshots, and so it can also be used to detect whether a snapshot was compiled to assembly or ELF. * The offset of the build ID description field from the text segment. * The length of the build ID description field. We replace the BSS offset in the Image object header with the offset of the ImageHeader object within the text segment, so that we can detect when a given Image has an ImageHeader object available. There are no methods available on ImageHeader objects, but instead the Image itself controls access to the information. In particular, the relocated address method either returns the relocated address information from the ImageHeader object or from the initialized BSS depending on the type of snapshot, so the caller need not do this work. Also, instead of returning the raw offset to the BSS section and having the caller turn that into an appropriate pointer, the method for accessing the BSS segment now returns a pointer to the segment. Bug: #43274 Cq-Include-Trybots: luci.dart.try:vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-precomp-android-release-arm_x64-try Change-Id: I15eae4ad0a088260b127f3d07da79374215b7f56 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/163207 Commit-Queue: Tess Strickland <sstrickl@google.com> Reviewed-by: Daco Harkes <dacoharkes@google.com>
The CL mentioned above has just landed (and I believe I've tested with enough trybots that don't expect a revert, but of course we'll see if anything surprising shows up). CL 163585 is a followup that does the same for assembly, including generating our own build ID section in assembly for ELF-native platforms. I plan to put it up for review now. It does leave the question open for what to do about snapshots that are split into multiple loading units (right now no build IDs are generated for such), but I've created #43516 for thinking about that as I don't think that's yet a primary workflow. |
Hi. We'd like to know if there's something we can help with. This is a blocker for flutter/flutter#59321 and we'd like to try our symbolication on the server as well, let us know if we could be of any help, thanks. |
So just to clarify the current state, ELF snapshots should already include a build ID that's also reported in non-symbolic stack traces. Assembly ones do not, for two major reasons:
The CL I mentioned above is still valid (though needs updating due to changes since), so I'll return to it now and see about getting it in. I think I'll actually split it into two parts:
With only the first, then you can correlate non-symbolic stack traces to the separate debugging information for both ELF and assembly, but you can only correlate them with unstripped snapshots for direct-to-ELF snapshots. That might be enough for all needs and the second CL may not be necessary. If we do the second as well, then there'll still be some work that I'll need to coordinate with Flutter and internal customers, to change their assembly process for snapshots in their toolchains to elide the assembler-added build ID. Until that happens, there'll be two build ID sections in each assembled ELF snapshot, only one of which will match the reported build ID in non-symbol stack traces, and I'm not sure how well external tools will handle multiple build ID sections. |
Compilers should place it in the When
Can you elaborate on this? As far as I'm aware, most tools in this space are aware of the build ID program header ( I still have to look into how your assembly process works, so please forgive me if I'm making wrong assumptions. Ideally, your assembly process does not care about build ids and lets standard tooling like the linker take care of that. If you have custom tooling for this, then the only thing to do is ensure the sections do not get removed or get copied (depending on whether you strip or split). Since the libraries are loaded into readable process memory at runtime, you need no further modifications to the binary. Usually, debuggers and crash reporting tools obtain a list of all loaded libraries that includes:
You can find examples for this in the Sentry Native SDK here: getsentry/sentry-native/src/modulefinder. We have actually started using this code for Flutter in the meanwhile, as it allows us to easily symbolicate frames even from third-party and system libraries using the standard approach for native symbolication:
|
By the way, I'm happy to contribute to this if you like, but may need some guidance for the places to look at in the Dart project. I thought it may be nice to share an example of how the information could be reported and how this looks in Sentry. Let's start with the library list read with the code I linked above. It includes the name of the library, the absolute memory range, and the build id called "Code ID": It's important to note that this list is much longer and includes all loaded libraries. It's definitely worth exposing all of them in case the stack trace includes system frames, or calls to third-party native modules. The reported and symbolicated stack trace then looks like this. We report the absolute addresses only: The corresponding relative addresses actually used for the lookup in debug information would then be these, for instance: |
Hi @sstrickl, |
Hi, is there any updates? Thanks! |
Closing we get the right debug files in each platform already |
Today the story to symbolicate stacktraces when DWARF information is split from the library is to pass the string stack trace, such as:
To the
native_stack_trace
tool, for example:Even though this is very straight forward, it has some limitations:
To address the first point, I'd like to ask (or propose) that the stacktrace include the relevant debug_id.
A
debug id
was added to generated ELF files and their debug files (when split) through this change, it would be helpful if that debug-id was included.native_stack_trace
could even check against that debug_id to make sure it in fact received the correct file as a parameter and warn the user otherwise.If that's no an option (i.e: don't want to change the exception string format), please provide an API that we can query in Dart to get the debug-id. That would be used by crash reporting tools ( like https://sentry.io ), to report which debug_id to use when symbolicating the stack trace on the server.
Point number 2 could be addressed by having a more fine grained API on
native_stack_trace
package to return a set of objects describing the stack trace (with frames and addresses). Or ideally a way to convert thedynamic
stacktrace at runtime to such representation, in order to avoid having to parse the string on the client to report the frames to the server.This is a blocker for this Flutter issue.
The text was updated successfully, but these errors were encountered: