Closed bruno-garcia closed 1 month ago
Hi @bruno-garcia, I think this should be cross-checked with @loewenheim because I am also not 100% sure what would be required if a non-minidump event needs to be symbolicated in the backend. We typically symbolicate client-side (via the symbols table) if we send raw stack traces (although I know that I used inproc
with raw stack frames in the event without client-side symbolication on Windows, so maybe that is a macOS-specific issue).
The best would be to check where the server-side symbolication fails. However, from the client side, a couple of things come to mind:
sentry_options_set_symbolize_stacktraces(options, false);
Otherwise, this would happen for all (expected) stack-frame locations during the event scope application. But I guess you're already doing that. I only wanted to ensure since it is not part of the posted code.
I am not sure whether any processing in the backend would take this as a hint of an already symbolicated stack frame, but I would not send the stack frames with function
, package
, or in_app
properties, but only raw instruction_addr
. You do this using sentry_value_set_stacktrace()
on the exception
object:
intptr_t frames[] = {
0x00010e532403,
0x00010e5327c5,
0x7ff810252344,
};
sentry_value_set_stacktrace(exception, (void*)frames, sizeof(frames)/sizeof(intptr_t));
values
listThe way you construct it, it results in:
"exception": [
{
"type": "Crash",
Whereas the docs say it should be
"exception": {
"values": [
{
"type": "Crash",
debug_meta
Maybe I misunderstood the task here, and the sending application is not the one from which the stack trace is produced, but if they are the same, then the Native SDK will send a more than complete module list with each event.
mechanism
in the exception
objectThis might also not be relevant to this particular issue, but mechanism.handled
, mechanism.synthetic
, and mechanism.type
affect how events are processed and rendered in the UI.
I don't see any other issues. Does this only happen when following this approach on macOS, or do you see the same issue on other platforms?
@bruno-garcia do we have a Sentry event showing this behavior?
I am also not 100% sure what would be required if a non-minidump event needs to be symbolicated in the backend.
We send C# and Unity errors that get symbolicated without a minidump so should work.
@bruno-garcia do we have a Sentry event showing this behavior?
I'll ask
We send C# and Unity errors that get symbolicated without a minidump so should work.
I understand it should work; as I wrote above, I had no issues symbolicating raw stack traces without client-side symbol lookup using inproc
on Windows (which, besides mentioned meta-data, uses the same interface as in the code above).
My point with "not 100% sure" was that since this is not a regular use case in the Native SDK, we might be missing meta-data when constructing the module list or the exception object that previously wasn't required but now is. With the module list, it could be platform-specific (e.g., the macOS module finder needs a fix). But in that case, I would still need feedback on where and why symbolication fails.
@bruno-garcia do we have a Sentry event showing this behavior?
@loewenheim, I can reproduce this quickly if it helps speed things up. Let me know.
@supervacuus I took a look at an example pair of events (one minidump, one "recreated" from it) today. The stacktraces were identical, but the modules weren't. Is that also the case in your recreation?
Hi @supervacuus, thanks for looking into this and for the tips. I'm going to try this on Windows, as well as disable client-side symbolication and send only raw instruction_addr
.
The exception interface requires a top-level values list
It seems that values
can be omitted according to the docs, but please let me know if that's not the case:
{
"exception": [
{
"type": "Error",
"value": "An error occurred",
"mechanism": {
"type": "generic",
"handled": false
}
}
]
}
There is no need to provide debug_meta Maybe I misunderstood the task here, and the sending application is not the one from which the stack trace is produced, but if they are the same, then the Native SDK will send a more than complete module list with each event.
Correct, we are considering a scenario where an out-of-process crash handler will collect all relevant information from a crashed app and report it to Sentry. In this case, I assume debug_meta
should be provided?
Hi @supervacuus, thanks for looking into this and for the tips. I'm going to try this on Windows, as well as disable client-side symbolication and send only raw
instruction_addr
.
Hi, @alex-gubernsky! While this was all sensible advice, thanks to your input and a short sync with @loewenheim, I can provide better feedback on the issue you are observing. You don't need to experiment with these options since this isn't an issue with the platform or stack trace metadata (although disabling client-side symbolication and only sending instruction_addr
is a good idea anyway).
We looked at your event and saw that the symbolication failed because the primary module the stack frames referenced was missing (i.e., the one you manually added to debug_meta.images
). This is because it will be overwritten by the module list of the current process when the event is prepared for sending.
Correct, we are considering a scenario where an out-of-process crash handler will collect all relevant information from a crashed app and report it to Sentry. In this case, I assume debug_meta should be provided?
Thanks, this is the most essential input to understand the issue. To support that use case, we would have to add an option to the SDK that turns off the application of the module list for each event. In that case, you have complete control over the images being sent.
A way to quickly verify this would be to write the debug_meta.images
in the before_send
hook instead of when constructing the event since the SDK invokes that hook after applying the scope to the event. Taking your example code:
sentry_value_t
add_debug_meta_before_send(sentry_value_t event, void *hint, void *closure)
{
// Remove the one we created for the currently running process (you could, of course, filter more specifically)
sentry_value_remove_by_key(event, "debug_meta");
// ... your `debug_meta` construction as you did in the example ...
sentry_value_set_by_key(event, "debug_meta", debug_meta);
return event;
}
int main()
{
// In your init code. The last parameter could provide access to a struct from
// which to retrieve debug_meta source data, it will be passed to each invocation
// as the `void *closure` parameter of the callback.
sentry_options_set_before_send(opts, add_debug_meta_before_send, NULL);
// ...
sentry_init(opts);
// ...
}
The exception interface requires a top-level values list
It seems that
values
can be omitted according to the docs, but please let me know if that's not the case:
Yes, sorry, my bad. I was surprised to find this to be an option.
Hi @supervacuus, thank you for your quick response!
A way to quickly verify this would be to write the debug_meta.images in the before_send hook instead of when constructing the event since the SDK invokes that hook after applying the scope to the event.
Ah, nice! I'll give it a try and let you know how it goes.
Hi @supervacuus,
A quick update: I can confirm that the reported images are no longer being overridden using the trick with the before_send
callback. I can see them present in the JSON after exporting an event, and there is also a slight change in behaviour in the UI, where instruction addresses are now displayed as relative. However, that’s pretty much it. The stack frames still cannot be symbolicated, so it seems like something is still missing.
I compared the JSONs from a real minidump event and the one constructed manually, and it seems the only differences are the number of images and the number of threads. Could that be the reason?
@alex-gubernsky @supervacuus: fyi @loewenheim opened a ticket to investigate why "synthetic" events aren't symbolicated
@loewenheim afaik this has been solved, correct?
Yes, this has been resolved by setting the mechanism type
field to a value other than minidump
.
Thank you for confirming @alex-gubernsky !
Using the following code:
Events don't get symbolicated, even though the memory address used is what came out of a minidump symbolication
Note that in the case of a JSON event sent, the address links are not clickable. Perhaps it's an indication of no connection to the symbol file?
Steps taken:
minidump