Skip to content

feat: Capturing fatal CPPExceptions via cxa_throw #5256

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

Merged
merged 41 commits into from
Jun 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
b234aef
feat: Capturing fatal CPPExceptions via cxa_throw
philipphofmann May 20, 2025
4176483
cleanup
philipphofmann May 20, 2025
b90f382
undo change
philipphofmann May 20, 2025
41c2945
fix test
philipphofmann May 20, 2025
9afafe8
readd strlcpy_safe
philipphofmann May 20, 2025
c553417
Merge branch 'main' into fix/cpp-exceptions-v3
philipphofmann May 21, 2025
0d78b39
fix tests
philipphofmann May 21, 2025
f1f8c42
with swapping
philipphofmann May 21, 2025
8b2cf40
Format code
getsentry-bot May 21, 2025
bd715da
undo
philipphofmann May 21, 2025
4f7816d
safeguard g_cxa_throw_handler
philipphofmann May 21, 2025
e9a42a7
Merge branch 'main' into fix/cpp-exceptions-v3
philipphofmann May 21, 2025
ab8424a
add to iOS sample
philipphofmann May 21, 2025
aa48954
another fix
philipphofmann May 21, 2025
cc56144
Merge branch 'main' into fix/cpp-exceptions-v3
philipphofmann May 22, 2025
2c3fe8a
again fix tests
philipphofmann May 22, 2025
10c25df
add testflight
philipphofmann May 22, 2025
a07340a
remove testflight
philipphofmann May 22, 2025
7b327ee
cleanup
philipphofmann May 22, 2025
1391461
Merge branch 'main' into fix/cpp-exceptions-v3
philipphofmann May 28, 2025
6242cd9
code review
philipphofmann May 28, 2025
3bbf0fe
more feedback
philipphofmann May 28, 2025
877a487
changelog
philipphofmann May 28, 2025
4c6f5e5
Merge branch 'main' into fix/cpp-exceptions-v3
philipphofmann Jun 3, 2025
466e9bd
Merge branch 'main' into fix/cpp-exceptions-v3
philipphofmann Jun 3, 2025
d1b3b97
Merge branch 'main' into fix/cpp-exceptions-v3
philipphofmann Jun 3, 2025
b19d42f
dprint
philipphofmann Jun 3, 2025
06d54e0
Merge branch 'main' into fix/cpp-exceptions-v3
philipphofmann Jun 4, 2025
065906c
fix changelog
philipphofmann Jun 4, 2025
e736e29
disable unswapping
philipphofmann Jun 4, 2025
aeb954d
not clearing pairs
philipphofmann Jun 4, 2025
26d6d49
cleanup
philipphofmann Jun 4, 2025
ea231f7
fix async safe logs
philipphofmann Jun 4, 2025
4e79ee5
Merge branch 'main' into fix/cpp-exceptions-v3
philipphofmann Jun 6, 2025
6dac07b
Update Sources/SentryCrash/Recording/Tools/SentryCrashCxaThrowSwapper.c
philipphofmann Jun 6, 2025
365e556
Update Sources/Sentry/include/SentryCompiler.h
philipphofmann Jun 6, 2025
6786dd6
more docs
philipphofmann Jun 6, 2025
8a01402
Update Sources/Swift/Core/SentryExperimentalOptions.swift
philipphofmann Jun 6, 2025
792d538
log message
philipphofmann Jun 6, 2025
1fae36c
comment on realloc
philipphofmann Jun 6, 2025
8a967cd
Merge branch 'main' into fix/cpp-exceptions-v3
philipphofmann Jun 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Features

- Capturing fatal CPPExceptions via hooking into cxa_throw when enabling `options.experimental.enableUnhandledCPPExceptionsV2 = true` (#5256)

### Improvements

- Crashes for uncaught NSExceptions will now report the stracktrace recorded within the exception (#5306)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ public struct SentrySDKWrapper {

// Experimental features
options.experimental.enableFileManagerSwizzling = !SentrySDKOverrides.Other.disableFileManagerSwizzling.boolValue
options.experimental.enableUnhandledCPPExceptionsV2 = true
}

func configureInitialScope(scope: Scope) -> Scope {
Expand Down
37 changes: 23 additions & 14 deletions Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -890,13 +890,13 @@
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="40A-vG-dFA">
<rect key="frame" x="0.0" y="134" width="320" height="268"/>
<rect key="frame" x="0.0" y="134" width="320" height="274.5"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="fn9-mQ-2PY">
<rect key="frame" x="0.0" y="0.0" width="320" height="140"/>
<rect key="frame" x="0.0" y="0.0" width="320" height="146.5"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="Q2k-6Y-RnD">
<rect key="frame" x="0.0" y="0.0" width="160" height="140"/>
<rect key="frame" x="0.0" y="0.0" width="160" height="146.5"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NFC-V3-lgW">
<rect key="frame" x="0.0" y="0.0" width="160" height="28"/>
Expand All @@ -907,31 +907,31 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Llv-Yz-cwF">
<rect key="frame" x="0.0" y="28" width="160" height="28"/>
<rect key="frame" x="0.0" y="29.5" width="160" height="28"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<state key="normal" title="Capture NSException"/>
<connections>
<action selector="captureNSException:" destination="QmU-DD-itF" eventType="touchUpInside" id="Gdl-wk-dUU"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wJ4-gS-64G" userLabel="fatalError">
<rect key="frame" x="0.0" y="56" width="160" height="28"/>
<rect key="frame" x="0.0" y="59.5" width="160" height="28"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<state key="normal" title="Throw FatalError"/>
<connections>
<action selector="captureFatalError:" destination="QmU-DD-itF" eventType="touchUpInside" id="dM5-xq-lrm"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ulu-26-dyP" userLabel="fatalDuplicateKeyError">
<rect key="frame" x="0.0" y="84" width="160" height="28"/>
<rect key="frame" x="0.0" y="89" width="160" height="28"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<state key="normal" title="Fatal Duplicate Key Error"/>
<connections>
<action selector="throwFatalDuplicateKeyError:" destination="QmU-DD-itF" eventType="touchUpInside" id="kze-Yw-k8f"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NYx-6R-0bb">
<rect key="frame" x="0.0" y="112" width="160" height="28"/>
<rect key="frame" x="0.0" y="118.5" width="160" height="28"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<state key="normal" title="OOM crash"/>
<connections>
Expand All @@ -941,7 +941,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="2CV-VI-MDY">
<rect key="frame" x="160" y="0.0" width="160" height="140"/>
<rect key="frame" x="160" y="0.0" width="160" height="146.5"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Zbo-2T-1Zm">
<rect key="frame" x="0.0" y="0.0" width="160" height="28"/>
Expand All @@ -953,24 +953,33 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="s6w-E3-5yE" userLabel="DiskWriteException">
<rect key="frame" x="0.0" y="35" width="160" height="28"/>
<rect key="frame" x="0.0" y="28" width="160" height="28"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<state key="normal" title="DiskWriteException"/>
<connections>
<action selector="diskWriteException:" destination="QmU-DD-itF" eventType="touchUpInside" id="p74-qC-kH7"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NNd-Ec-zXw">
<rect key="frame" x="0.0" y="70.5" width="160" height="28"/>
<rect key="frame" x="0.0" y="56" width="160" height="28"/>
<accessibility key="accessibilityConfiguration" label="crashTheApp"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<state key="normal" title="Crash the app"/>
<connections>
<action selector="crash:" destination="QmU-DD-itF" eventType="touchUpInside" id="qlZ-bL-KUT"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ptW-5o-Xrh" userLabel="Unhandled C++ Exception">
<rect key="frame" x="0.0" y="84" width="160" height="28"/>
<accessibility key="accessibilityConfiguration" label="crashTheApp"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<state key="normal" title="Unhandled C++ Exception"/>
<connections>
<action selector="unhandledCppException:" destination="QmU-DD-itF" eventType="touchUpInside" id="T1y-uf-e08"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wJs-Av-cg2">
<rect key="frame" x="0.0" y="105.5" width="160" height="34.5"/>
<rect key="frame" x="0.0" y="112" width="160" height="34.5"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="Use-after-free"/>
<connections>
Expand All @@ -982,7 +991,7 @@
</subviews>
</stackView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="1zm-ho-TCr">
<rect key="frame" x="0.0" y="140" width="320" height="128"/>
<rect key="frame" x="0.0" y="146.5" width="320" height="128"/>
<constraints>
<constraint firstAttribute="height" constant="128" id="lc6-97-p3W"/>
</constraints>
Expand Down Expand Up @@ -1172,7 +1181,7 @@
<rect key="frame" x="0.0" y="336" width="152" height="38"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" adjustsImageSizeForAccessibilityContentSizeCategory="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="YhG-k9-4vd">
<rect key="frame" x="0.0" y="0.0" width="76" height="38"/>
<rect key="frame" x="0.0" y="0.0" width="78" height="38"/>
<accessibility key="accessibilityConfiguration" identifier="io.sentry.ui-test.button.show-widget"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="Show Widget">
Expand All @@ -1183,7 +1192,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" adjustsImageSizeForAccessibilityContentSizeCategory="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fqi-kr-TkL">
<rect key="frame" x="76" y="0.0" width="76" height="38"/>
<rect key="frame" x="78" y="0.0" width="74" height="38"/>
<accessibility key="accessibilityConfiguration" identifier="io.sentry.ui-test.button.hide-widget"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="Hide Widget">
Expand Down
5 changes: 5 additions & 0 deletions Samples/iOS-Swift/iOS-Swift/ErrorsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ class ErrorsViewController: UIViewController {
}
}

@IBAction func unhandledCppException(_ sender: Any) {
let cpp = CppWrapper()
cpp.throwCPPException()
}

// swiftlint:disable force_unwrapping
@IBAction func unwrapCrash(_ sender: UIButton) {
highlightButton(sender)
Expand Down
8 changes: 8 additions & 0 deletions Samples/iOS-Swift/iOS-Swift/Tools/CppCode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "CppCode.hpp"
#include <stdexcept>

void
Sentry::CppCode::throwCPPException(void)
{
throw std::invalid_argument("Invalid Argument.");
}
15 changes: 15 additions & 0 deletions Samples/iOS-Swift/iOS-Swift/Tools/CppCode.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef CppCode_h
#define CppCode_h
#if defined __cplusplus

# include <stdio.h>

namespace Sentry {
class CppCode {
public:
void throwCPPException();
};
}

#endif /* __cplusplus */
#endif /* CppSample_hpp */
5 changes: 5 additions & 0 deletions Samples/iOS-Swift/iOS-Swift/Tools/CppWrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#import <Foundation/Foundation.h>

@interface CppWrapper : NSObject
- (void)throwCPPException;
@end
13 changes: 13 additions & 0 deletions Samples/iOS-Swift/iOS-Swift/Tools/CppWrapper.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#import "CppWrapper.h"
#import "CppCode.hpp"
#import <Foundation/Foundation.h>

@implementation CppWrapper

- (void)throwCPPException
{
Sentry::CppCode cpp;
cpp.throwCPPException();
}

@end
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#import "CppWrapper.h"
#import "SentryBenchmarking.h"
#import "SentryExposure.h"
#import <Sentry/PrivateSentrySDKOnly.h>
Expand Down
Loading
Loading