-
-
Notifications
You must be signed in to change notification settings - Fork 333
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
fix: read free_memory when the event is captured, not only at SDK startup #1962
fix: read free_memory when the event is captured, not only at SDK startup #1962
Conversation
I think I understood the issue and the comment in the GH issue correctly, and made the changes as you see here. However, I'm getting SentryCrashIntegrationTests failures when running the entire Sentry testsuite, but they pass correctly when running only the SentryCrashIntegrationTests tests. Could someone take a look, see if I'm on the right track, and maybe have an idea what's going on with the tests? |
Co-authored-by: Dhiogo Brustolin <[email protected]>
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.
Some important notes.
Sources/Sentry/SentryClient.m
Outdated
NSMutableDictionary *device = | ||
[[NSMutableDictionary alloc] initWithDictionary:context[@"device"]]; | ||
|
||
NSDictionary *systemInfo = [[SentryCrashWrapper sharedInstance] systemInfo]; |
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.
h
: The freeMemory
in systemInfo
is cached. If you log the freeMemory like this
[SentryLog logWithMessage:[NSString stringWithFormat:@"FreeMemory %@", systemInfo[@"freeMemory"]] andLevel:kSentryLevelInfo];
you see that it doesn't change when you capture events.
SentryCrash uses this methods to get the free and usable memory
sentry-cocoa/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.m
Lines 191 to 213 in ce1b8d1
static uint64_t | |
freeMemory(void) | |
{ | |
vm_statistics_data_t vmStats; | |
vm_size_t pageSize; | |
if (VMStats(&vmStats, &pageSize)) { | |
return ((uint64_t)pageSize) * vmStats.free_count; | |
} | |
return 0; | |
} | |
static uint64_t | |
usableMemory(void) | |
{ | |
vm_statistics_data_t vmStats; | |
vm_size_t pageSize; | |
if (VMStats(&vmStats, &pageSize)) { | |
return ((uint64_t)pageSize) | |
* (vmStats.active_count + vmStats.inactive_count + vmStats.wire_count | |
+ vmStats.free_count); | |
} | |
return 0; | |
} |
Ideally, I think we should call the same methods. We could make these functions available for internal usage by adding them to SentryCrashMonitor_System.h
and then exposing them via the SentryCrashWrapper.
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.
By switching to SentryCrash.sharedInstance.systemInfo
like @brustolin suggested, we get the uncached value and adding the log indeed shows it does change. Do you think that is an acceptable fix, or do you want to call the freeMemory method like you suggested?
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.
Really SentryCrash.sharedInstance.systemInfo
is uncached? I would be surprised. It didn't work for me 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.
My logs were definitely showing different values. With you they always shows the same?
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.
SentryCrash.sharedInstance.systemInfo
is uncached
SentryCrashWrapper.sharedInstance.systemInfo
is cached
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.
Yeah that's what I am seeing as well
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.
SentryCrash.sharedInstance.systemInfo
has a lit bit of overhead because all of the information retrieved. Wondering if just exposing the freeMemory
function is not a better solution.
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.
Alrighty, done. Confirmed that it works by sending multiple events and errors, and seeing the value actually change. Now, how would we unit test this?
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.
The overall approach LGTM. The only thing missing are tests, I think.
That's what I said in my last comment as well: "Now, how would we unit test this?" Because I don't really know how we'd test this? |
We already have some Event tests, all you need to add Is a check whether the memory information is also attached to the event. Make sure this information is not added to OOM events. Maybe use the free memory to compare with the information in the event with some degree of difference, I don't believe calling free_memory twice would result in the same value. |
We already have It feels kinda uncertain to just capture 2 events and see if their free memory value is different, but yeah I'm not sure how else to do this, apart from mocking the actual function that gets the free memory, and I am not sure if that's worth it? So I did it like you suggested, and the test passes. |
Ok, the unit test passes locally but fails on CI. I don't think this is the best way to test this. |
Yeah, this will be trick to test. I doubt you get two equal values out of this function, because free memory is changing all the time. @philipphofmann any suggestion? |
I spoke about this with Philip, and I am now doing a test where we're injecting a known value of free memory via SentryCrashWrapper. |
A little bit of overkill, but it works. Good. |
* master: ci: Don't run benchmarks on release (#1971) Don't track OOMs for simulators (#1970) feat: Automatic nest new spans with the ui life cycle function (#1959) docs: update some docs/comments to read a little better (#1966) ci: benchmarking updates (#1926) feat: upload list of slow/frozen rendered frame timestamps during a profile (#1910) feat: Enhance the UIViewController breadcrumbs with more data (#1945) # Conflicts: # Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.h
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.
LGTM
Why did this get auto merged when there are build failures? I'll create a new PR to fix the lint issue. |
And why didn't I get this same error locally when building? Seems strange that some errors are only enabled in CI? |
* master: ref: Fix linter error (#1981) fix: read free_memory when the event is captured, not only at SDK startup (#1962) fix: Remove Sentry keys from cached HTTP request headers (#1975) release: 7.21.0 ci: Don't run benchmarks on release (#1971) Don't track OOMs for simulators (#1970) feat: Automatic nest new spans with the ui life cycle function (#1959) docs: update some docs/comments to read a little better (#1966) ci: benchmarking updates (#1926) feat: upload list of slow/frozen rendered frame timestamps during a profile (#1910)
📜 Description
When we capture an event, we now enhance the data with the actual free memory at that time. Until now we only used the value from when the SDK was initiated.
💡 Motivation and Context
Fixes #1824
💚 How did you test it?
Unit test
📝 Checklist
🔮 Next steps