Skip to content
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

Merged
merged 14 commits into from
Jul 18, 2022

Conversation

kevinrenskers
Copy link
Contributor

@kevinrenskers kevinrenskers commented Jul 12, 2022

📜 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

  • I reviewed the submitted code
  • I added tests to verify the changes
  • I updated the docs if needed
  • Review from the native team if needed
  • No breaking changes

🔮 Next steps

@kevinrenskers
Copy link
Contributor Author

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?

kevinrenskers and others added 2 commits July 13, 2022 10:03
* master:
  fix: Crash in profiling logger (#1964)
  ref: Mark options.sdkInfo as deprecated (#1960)
  feat: Add extra app start span (#1952)
Copy link
Member

@philipphofmann philipphofmann left a 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 Show resolved Hide resolved
NSMutableDictionary *device =
[[NSMutableDictionary alloc] initWithDictionary:context[@"device"]];

NSDictionary *systemInfo = [[SentryCrashWrapper sharedInstance] systemInfo];
Copy link
Member

@philipphofmann philipphofmann Jul 13, 2022

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

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.

Copy link
Contributor Author

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?

Copy link
Member

@philipphofmann philipphofmann Jul 13, 2022

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.

Copy link
Contributor Author

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?

Copy link
Contributor

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

Copy link
Contributor Author

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

Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Member

@philipphofmann philipphofmann left a 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.

@kevinrenskers
Copy link
Contributor Author

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?

@brustolin
Copy link
Contributor

brustolin commented Jul 14, 2022

Now, how would we unit 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.

@kevinrenskers
Copy link
Contributor Author

We already have testCaptureOOMEvent_RemovesFreeMemoryFromContext.

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.

@kevinrenskers kevinrenskers marked this pull request as ready for review July 14, 2022 10:05
@kevinrenskers
Copy link
Contributor Author

Ok, the unit test passes locally but fails on CI. I don't think this is the best way to test this.

@brustolin
Copy link
Contributor

brustolin commented Jul 14, 2022

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.
The alternative is to write a wrapper to use in the event, I dont like this idea.

@philipphofmann any suggestion?

@kevinrenskers
Copy link
Contributor Author

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.

@brustolin
Copy link
Contributor

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
@kevinrenskers kevinrenskers enabled auto-merge (squash) July 14, 2022 16:22
Copy link
Contributor

@brustolin brustolin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kevinrenskers kevinrenskers merged commit 9640294 into master Jul 18, 2022
@kevinrenskers kevinrenskers deleted the fix/1824-read-free-memory-at-time-of-event branch July 18, 2022 07:16
@kevinrenskers
Copy link
Contributor Author

Why did this get auto merged when there are build failures? I'll create a new PR to fix the lint issue.

@kevinrenskers
Copy link
Contributor Author

And why didn't I get this same error locally when building? Seems strange that some errors are only enabled in CI?

kevinrenskers added a commit that referenced this pull request Jul 18, 2022
* 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)
@kevinrenskers kevinrenskers mentioned this pull request Aug 1, 2022
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Device free_memory isn't read at the time the event is captured
3 participants