Skip to content

Commit

Permalink
fix(sdk-crash-detection): Reverse frame order (#49746)
Browse files Browse the repository at this point in the history
The stack trace frames are ordered from caller to callee, or oldest to
youngest. Therefore, we must reverse the frame order when iterating
over the frames to detect an SDK crash.

This PR is based on #49593.

Co-authored-by: Joris Bayer <joris.bayer@sentry.io>
Co-authored-by: Arpad Borsos <arpad.borsos@sentry.io>
  • Loading branch information
3 people authored Jun 5, 2023
1 parent 082ddda commit cf3d1fc
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 10 deletions.
5 changes: 4 additions & 1 deletion src/sentry/utils/sdk_crashes/cocoa_sdk_crash_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ def is_sdk_crash(self, frames: Sequence[Mapping[str, Any]]) -> bool:
if not frames:
return False

for frame in frames:
# The frames are ordered from caller to callee, or oldest to youngest.
# The last frame is the one creating the exception.
# Therefore, we must iterate in reverse order.
for frame in reversed(frames):
if self.is_sdk_frame(frame):
return True

Expand Down
7 changes: 6 additions & 1 deletion tests/sentry/utils/sdk_crashes/test_fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def get_sentry_frame(function: str, in_app: bool = False) -> Mapping[str, Any]:


def get_frames(function: str, sentry_frame_in_app: bool = False) -> Sequence[Mapping[str, Any]]:
return [
frames = [
get_sentry_frame(function, sentry_frame_in_app),
{
"function": "LoginViewController.viewDidAppear",
Expand Down Expand Up @@ -73,6 +73,11 @@ def get_frames(function: str, sentry_frame_in_app: bool = False) -> Sequence[Map
},
]

# The frames have to be ordered from caller to callee, or oldest to youngest.
# The last frame is the one creating the exception.
# As we usually look at stacktraces from youngest to oldest, we reverse the order.
return frames[::-1]


def get_crash_event(handled=False, function="-[Sentry]", **kwargs) -> Sequence[Mapping[str, Any]]:
return get_crash_event_with_frames(get_frames(function), handled=handled, **kwargs)
Expand Down
16 changes: 8 additions & 8 deletions tests/sentry/utils/sdk_crashes/test_sdk_crash_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,26 +264,26 @@ def test_frames_only_in_app_after_sentry_frame_not_reported(self, mock_sdk_crash
self.execute_test(
get_crash_event_with_frames(
[
IN_APP_FRAME,
{
"function": "__handleUncaughtException",
"symbol": "__handleUncaughtException",
"package": "CoreFoundation",
"function": "std::__terminate",
"symbol": "_ZSt11__terminatePFvvE",
"package": "libc++abi.dylib",
"in_app": False,
},
get_sentry_frame("sentrycrashdl_getBinaryImage"),
{
"function": "_objc_terminate",
"symbol": "_ZL15_objc_terminatev",
"package": "libobjc.A.dylib",
"in_app": False,
},
get_sentry_frame("sentrycrashdl_getBinaryImage"),
{
"function": "std::__terminate",
"symbol": "_ZSt11__terminatePFvvE",
"package": "libc++abi.dylib",
"function": "__handleUncaughtException",
"symbol": "__handleUncaughtException",
"package": "CoreFoundation",
"in_app": False,
},
IN_APP_FRAME,
]
),
False,
Expand Down

0 comments on commit cf3d1fc

Please sign in to comment.