-
-
Notifications
You must be signed in to change notification settings - Fork 213
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
sentry-native SDK integration #2704
Conversation
|
</None> | ||
</ItemGroup> | ||
|
||
<ItemGroup Condition="'$(CI_PUBLISHING_BUILD)' == 'true' or $([MSBuild]::IsOsPlatform('Linux'))"> |
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 imagine this CI_PUBLISHING_BUILD
stuff is on the other binding projects and got copied here. But why do we need this? I'm concerned about stuff behaving differently in CI vs locally
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.
It's intentional here though not yet necessary, I've extracted that as a "next step" in the PR description:
collect both platforms for the nuget package when running in CI
As to why: because we can't build all platforms on a single machine and I don't really want to do the download from a CI job the way I had to do in sentry-unity because that is very painful whenever there's a change, e.g. you want to run different sentry-native version on your branch than what has been compiled as an artifact on the main branch.
The way this project is currently implemented is that it compiles for your platform locally and only if necessary (i.e. sentry-native submodule checkout has changed or if there's a change in this Sentry.Bindings.Native.csproj
file). In CI, it will collect and package for all platforms. At least that's the idea.
{ | ||
relocations.Add(GetRelativeAddressMode(i), GetRelativeAddressMode(@event.DebugImages.Count)); | ||
@event.DebugImages.Add(DebugImages[i]); | ||
_options.LogWarning("Unexpected debug image: neither ModuleVersionId nor ImageAddress is defined: {0}", DebugImages[i].ToString()); |
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.
No ToString
seems to be implemented here:
sentry-dotnet/src/Sentry/DebugImage.cs
Line 10 in 61fb2ee
public sealed class DebugImage : IJsonSerializable |
Did you mean to add one? Or access a property here instead?
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.
Shouldn't really happen, I've removed .ToString() and added a Debug.Assert()
I've update a description a bit (also make sure to read the issue first as that's where the problem statement is). However, it may still be insufficient if you're not very familiar with the native integrations (and native stack trace handling). In that case, either let me know and I'll try to walk you through some relevant bits or maybe someone else would have a chance to review this in the meantime. |
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.
You mentioned you'll move the ImageAddress
type change to another PR?
0ba14ff
to
29d02a4
Compare
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.
Similar to @bitsandfoxes, it'd be really good to get a breakdown of the changes in this file. I'll try to put some specific questions in where I've got enough context to ask something sensible 😉
|
||
if (!found) | ||
{ | ||
relocations.Add(GetRelativeAddressMode(i), GetRelativeAddressMode(@event.DebugImages.Count)); |
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.
Why @event.DebugImages.Count
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.
because that's the index we're adding the image at on the next line.
@@ -88,25 +91,55 @@ internal void MergeDebugImagesInto(SentryEvent @event) | |||
Dictionary<string, string> relocations = new(); |
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.
We only get this far if there are already debug images on the event... from the comments above, it seems that only ever happens when there are InnerExceptions (and so multiple stack traces) - correct?
I guess a high level question at that point: What is the information that could overlap from one stack trace to another, in this scenario and how/what are we trying to merge here?
{ | ||
if (i != j) | ||
if (DebugImages[i].ModuleVersionId == @event.DebugImages[j].ModuleVersionId) |
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.
Is this what we mean by ModuleVersionId here? That seems to identify a particular assembly... I take it the offsets in PDBs are module relative. I'm wondering what relocations is doing then... my best guess is that maybe the modules are stored in a different order in each of the different stack traces, but we only send the modules once in the SentryEvent so we need to map debug images from each stack trace to the correct module index to get the correct offsets??? It's just as likely that I have no idea whatsoever what's going on here though 😜
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.
Firstly, this code is actually old, it's just moved under a if (DebugImages[i].ModuleVersionId is not null)
condition so not really in need for reviewing (#2050). Also, this would be a good read if you wanted to start looking into this topic: https://github.com/getsentry/rfcs/blob/main/text/0013-portable-pdb.md
But I'll try to answer your questions to the best of my knowledge (and memory :) ):
Is this what we mean by ModuleVersionId here?
yes
I'm wondering what relocations is doing then...
To Sentry (backend), we're sending a list of debug images and each stack frame references an image in this list by "rel:IMAGE_INDEX"
(see addr_mode
).
my best guess is that maybe the modules are stored in a different order in each of the different stack traces
correct
, but we only send the modules once in the SentryEvent so we need to map debug images from each stack trace to the correct module index to get the correct offsets???
kinda - we can send the same image multiple times but it's wasteful. One could argue that running this code is also wasteful, but to me, it feels better to run the code once on the client and reduce the payload (less stuff to serialize, transfer, deserialize and process, store)
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.
At least as far as I understand, it looks good. Most of the meat is in DebugStackTrace.cs
and we try to get a managed stack trace but now, failing that, fall back on native stack traces.
One important question is, other than the fact that it compiles, how do we know it works? Do we have any automated tests for this or was it just manual smoke tests?
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.
Since the outstanding questions were unrelated to the changes made in this PR, I'm merging
{ | ||
if (i != j) | ||
if (DebugImages[i].ModuleVersionId == @event.DebugImages[j].ModuleVersionId) |
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.
Firstly, this code is actually old, it's just moved under a if (DebugImages[i].ModuleVersionId is not null)
condition so not really in need for reviewing (#2050). Also, this would be a good read if you wanted to start looking into this topic: https://github.com/getsentry/rfcs/blob/main/text/0013-portable-pdb.md
But I'll try to answer your questions to the best of my knowledge (and memory :) ):
Is this what we mean by ModuleVersionId here?
yes
I'm wondering what relocations is doing then...
To Sentry (backend), we're sending a list of debug images and each stack frame references an image in this list by "rel:IMAGE_INDEX"
(see addr_mode
).
my best guess is that maybe the modules are stored in a different order in each of the different stack traces
correct
, but we only send the modules once in the SentryEvent so we need to map debug images from each stack trace to the correct module index to get the correct offsets???
kinda - we can send the same image multiple times but it's wasteful. One could argue that running this code is also wasteful, but to me, it feels better to run the code once on the client and reduce the payload (less stuff to serialize, transfer, deserialize and process, store)
|
||
if (!found) | ||
{ | ||
relocations.Add(GetRelativeAddressMode(i), GetRelativeAddressMode(@event.DebugImages.Count)); |
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.
because that's the index we're adding the image at on the next line.
And there will be an integration test for Native AOT once we can build one, see "Next steps" in the PR description |
OK, but none of those tests changed in the PR right? And we'd need to be generating native debug images for any of the new code to get tested so I think those tests are just ensuring the PR doesn't break any existing functionality with managed code??? We will test the new code once we have the Native AOT integration tests though, so that answers my question. |
🤯 OMG I had no idea those existed - thank you! |
Summary of the changes
sentry-native
submodule.NativeLibrary
andDirectPInvoke
if a dependant app is AOT compiled. The static libs mean end-users don't get an additional library alongside their single executable 🥳Next steps
#skip-changelog