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

Collect and report all types of crashes together with full stack trace information #250

Merged
merged 2 commits into from
Jan 17, 2023

Conversation

matux
Copy link
Collaborator

@matux matux commented Jan 17, 2023

Description of the change

This PR rewrites the entire mechanism by which we detect and collect crash reports together with stack traces:

  • Removed PLCrashReporter.
  • This removes the requirement for users unnecessarily having to research and choose a crash hooking mechanism on their own.
  • Fix how we use KSCrash to hook to the OS signals and exceptions.
  • We attempt a partial symbolication locally.
  • The hooking mechanism is disabled for runs with a debugger attached, so we don't interfere with the developer own debugging.
  • And more...

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Maintenance
  • New release

Related issues

Checklists

Development

  • Lint rules pass locally
  • The code changed/added as part of this pull request has been covered with tests
  • All tests related to the changed code pass in development

Code review

  • This pull request has a descriptive title and information useful to a reviewer. There may be a screenshot or screencast attached
  • "Ready for review" label attached to the PR and reviewers assigned
  • Issue from task tracker has a link to this pull request
  • Changes have been reviewed by at least one other engineer

@matux matux requested a review from ijsnow January 17, 2023 18:59
@matux matux self-assigned this Jan 17, 2023
@matux matux changed the base branch from master to collect_crashes_with_stacktraces January 17, 2023 18:59
[super install];

KSCrashMonitorType monitoring = isDebuggerAttached()
? KSCrashMonitorTypeDebuggerSafe & ~(KSCrashMonitorTypeOptional | KSCrashMonitorTypeExperimental)
Copy link

Choose a reason for hiding this comment

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

What does the ~ do?

Copy link
Collaborator Author

@matux matux Jan 17, 2023

Choose a reason for hiding this comment

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

Prefix ~ is bitwise negation. It basically flips the integer bits:

So say some x is 5 and it's type is a 16-bit representation of an integer:

0000000000000101

~x would turn that into:

1111111111111010`

In our case, we use it to flip the bitwise-OR of (Optional, Experimental), effectively turning those bits to 0 in DebuggerSafe, and thus, removing those two monitors we don't want.

So, let's say we have 4 integers of 4 bits:

monitor_a = 1 = b0001
monitor_b = 2 = b0010
monitor_c = 4 = b0100
monitor_d = 8 = b1000

And say only a, c and d are debugger safe:

debugger_safe = monitor_a | monitor_c | monitor_d = b1101

And that we want to use debugger_safe but not monitor_d:

monitors_i_want = debugger_safe & ~monitor_d = b0101
  1. monitor_d is b1000
  2. ~monitor_d flips its bits, from b1000 to b0111
  3. debugger_safe is b1101
  4. b1101 & b0111 = b0101
1st bit = true && true = true (1)
2nd bit = false && true = false (0)
3rd bit = true && true = true (1)
4th bit = true && false = false (0)

Which effectively has the bits corresponding to monitor_a and monitor_c. Which are the ones we want.

Bitwise operations are simply boolean operations over bits where 1 means true and 0 false.

All in all, this is a horrible way of on/off options that I would never suggest unless you're extremely constrained by memory and performance. And even on those cases, LLVM is smart enough to do it for you.

Copy link

Choose a reason for hiding this comment

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

Ahh ok it didn't register to me that this was effectively just configuration flags. Makes sense!

@"short_version": shortVersion ? shortVersion : @"",
@"bundle_identifier": bundleIdentifier ? bundleIdentifier : @"",
@"app_name": bundleName ? bundleName : [[NSProcessInfo processInfo] processName]
@"code_version": version ?: @"",
Copy link

Choose a reason for hiding this comment

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

Is a ?: b in obj-c basically saying a or b if a doesn't exist? Shorthand for the ternary you removed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Exactly. It's called the Elvis operator, and since what's being compared is a pointer to a value, if the value doesn't exist, the pointer points to 0, and 0 is false. If the value exists, the pointer points to "something that is not 0", and that means true.

Copy link

@ijsnow ijsnow left a comment

Choose a reason for hiding this comment

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

Looks good

RollbarSdkLog(@"Column: %s", column[i]);
RollbarSdkLog(@"Data: %s", data[i]);
}
// RollbarSdkLog(@"Columns: %d", columns);
Copy link

Choose a reason for hiding this comment

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

Whats the value in keeping this around?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'd like for our users to decide whether Rollbar spits output to the console or not. Right now, it spits everything and makes the console unusable. I commented out these because I want to restore them later behind some on/off flag.

@@ -294,7 +294,7 @@ - (void)queuePayload_OnlyCallOnThisThread:(nonnull NSArray *)data {
}

- (void)savePayload:(nonnull RollbarPayload *)payload withConfig:(nonnull RollbarConfig *)config {

//RollbarSdkLog(@"RollbarThread::savePayload: %@", payload.data.body);
Copy link

Choose a reason for hiding this comment

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

same... debugging for later?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Same as above. I'd rather not lose these and restore them properly later. There are a ton of places where we output and I don't wanna go into a day-long hunt and would rather just search for //RollbarSdkLog.

I'd say this is certainly not good practice, but these are special circumstances 😛.

@matux matux merged commit 6d3b146 into collect_crashes_with_stacktraces Jan 17, 2023
@matux matux deleted the collect branch January 17, 2023 19:48
@matux matux mentioned this pull request Jan 17, 2023
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants