Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
22cc593
Initial implementation
mujacica Oct 28, 2025
c08fdb4
Update build structure and daemon
mujacica Oct 29, 2025
14acb34
Updates for Windows support
mujacica Oct 29, 2025
5edcb7d
Fix logging
mujacica Oct 29, 2025
02a6d71
Fix MacOs builds
mujacica Oct 29, 2025
5395f73
Fix Warnings
mujacica Oct 29, 2025
4951eda
Test fixes
mujacica Oct 29, 2025
9c0fd1b
Fix linux builds
mujacica Oct 29, 2025
a71cf41
Fix linux/mac modules
mujacica Oct 29, 2025
18e5eb4
Fix concurency
mujacica Oct 29, 2025
1bd917c
Fix build errors
mujacica Oct 29, 2025
6a6e5c2
Formatting
mujacica Oct 29, 2025
d5e589d
Fix 32bit builds
mujacica Oct 29, 2025
6557ce8
Fix format
mujacica Oct 29, 2025
6a7dc03
Fix some issues
mujacica Oct 29, 2025
931e568
Native tests need http/transport
mujacica Oct 29, 2025
95728b6
Fix CMake
mujacica Oct 29, 2025
94f3250
Fix build
mujacica Oct 29, 2025
d7ef2a6
Fix errors
mujacica Oct 30, 2025
3958e80
Fix format
mujacica Oct 30, 2025
5d8ba3f
Fix style
mujacica Oct 30, 2025
da3e584
Fix some of the issues
mujacica Oct 30, 2025
1f9789c
Fix format
mujacica Oct 30, 2025
203d113
Moooore fixes
mujacica Oct 30, 2025
866b4f0
Debug CI
mujacica Oct 30, 2025
f2719fc
More debug
mujacica Oct 30, 2025
0a01c55
More debug
mujacica Oct 30, 2025
9ddbfe9
More debug
mujacica Oct 30, 2025
ccf1116
And more
mujacica Oct 30, 2025
763eb4e
More fixes
mujacica Oct 30, 2025
bf68a47
Linux fixes
mujacica Oct 30, 2025
3d03bc7
Fix i386 builds
mujacica Oct 30, 2025
cb4d344
More fixes
mujacica Oct 30, 2025
c549dfa
Fix more tests
mujacica Oct 30, 2025
6c89dd3
More fixes
mujacica Oct 30, 2025
e4cd98c
Fix native backend daemon discovery and resource leaks
mujacica Jan 15, 2026
c207047
fix: use signal-safe memory operations in crash handler for TSAN/ASAN…
mujacica Jan 15, 2026
2a73c81
Fix TSAN test failures and unused function warnings
mujacica Jan 15, 2026
9fc64c0
Fix TSAN robustness for native crash HTTP tests
mujacica Jan 15, 2026
8704fe5
Fix native test failures under kcov and sanitizers
mujacica Jan 15, 2026
5b4e618
Add run_crash helper to handle kcov exit code quirk
mujacica Jan 15, 2026
e36f3b0
Fix Windows ClangCL build and improve signal handler robustness
mujacica Jan 15, 2026
971f631
Fix format
mujacica Jan 15, 2026
bc64d6c
Fix Windows ARM64 and macOS ASAN CI failures
mujacica Jan 15, 2026
c6009b6
Fix tests
mujacica Jan 15, 2026
1a6c927
Fix Windows/ASAN CI failures and add crash reporting mode API
mujacica Jan 15, 2026
52388b5
Fix Windows/ASAN CI failures and add crash reporting mode API
mujacica Jan 15, 2026
3e43337
Fix attachment handling in native crash daemon with native stacktrace…
mujacica Jan 15, 2026
13c0b91
Fix attachment handling in native crash daemon with native stacktrace…
mujacica Jan 15, 2026
065da6f
Fix CI failures: Windows ClangCL build and resource leaks
mujacica Jan 15, 2026
eb77775
Fix macOS minidump resource leaks and uninitialized state
mujacica Jan 15, 2026
b08e3ac
Skip native backend tests on macOS ASAN
mujacica Jan 15, 2026
2b3ee1c
Add E2E tests and fix thread duplication in native-with-minidump mode
mujacica Jan 15, 2026
2ca9ab9
Add debug symbol upload to E2E workflow for symbolication
mujacica Jan 15, 2026
4f85ef5
Fix debug_meta to use crashed process modules instead of daemon modules
mujacica Jan 15, 2026
64cb846
Add missing sys/uio.h header and fix code style
mujacica Jan 15, 2026
3110fe7
Fix Python formatting in E2E tests
mujacica Jan 15, 2026
96963c5
Reduce thread count assertion from >= 3 to >= 1
mujacica Jan 15, 2026
a0ad781
Add Linux module capture from /proc/maps for debug_meta
mujacica Jan 15, 2026
9f1964c
Remove debug symbol upload from E2E workflow
mujacica Jan 15, 2026
4a70066
Fix unused parameter warning on Windows
mujacica Jan 15, 2026
d17f0fa
Fix ELF debug_id byte swapping for Linux module capture
mujacica Jan 15, 2026
7f7ef26
Add Linux thread enumeration from /proc/task for native mode
mujacica Jan 15, 2026
31ee726
Fix code style
mujacica Jan 15, 2026
cf804f7
Enable structured logs in E2E crash tests
mujacica Jan 15, 2026
1f2cebf
Fix Linux module capture and ARM64 stack unwinding
mujacica Jan 15, 2026
b83de19
Fix Windows 32-bit compile warnings for uint64_t to size_t conversion
mujacica Jan 16, 2026
e68b2b5
Increase E2E test polling to 100 attempts with 6 second intervals
mujacica Jan 16, 2026
53173e4
Add PE code_id for Windows modules in native crash events
mujacica Jan 16, 2026
21fb6f4
Improve Windows stack capture for frame pointer unwinding
mujacica Jan 16, 2026
2de8ed0
Use StackWalk64 for Windows stack unwinding in native backend
mujacica Jan 16, 2026
29dca8a
Fix Windows build: add forward declaration for walk_stack_with_dbghelp
mujacica Jan 16, 2026
c778271
Add module enrichment to stack frames and build stacktraces for all t…
mujacica Jan 16, 2026
c3bafa7
Fix empty frames and use per-thread context for Linux
mujacica Jan 16, 2026
8b3565d
Fix unused variable warning on Windows ClangCL build
mujacica Jan 16, 2026
e91416c
Fix Linux module size calculation to span all memory mappings
mujacica Jan 16, 2026
3546af3
Fix GUID alignment issue when reading PDB debug info on Windows
mujacica Jan 16, 2026
e544770
Add diagnostic logging for Windows vs Linux debug_meta investigation
mujacica Jan 16, 2026
0304e9f
Add diagnostic logging for Windows vs Linux debug_meta investigation
mujacica Jan 16, 2026
d38b5e1
Add debug_file and fix code_id format for Windows native backend
mujacica Jan 16, 2026
855e25a
Add debug_file and fix code_id format for Windows native backend
mujacica Jan 17, 2026
464a622
More windows fixes + PR fixes
mujacica Jan 19, 2026
8ce7cd0
Fix minidump writer issues from PR review
mujacica Jan 20, 2026
71ea60d
Fix minidump writer issues from PR review (part 2)
mujacica Jan 20, 2026
f64296c
Fix shared memory corruption and ELF parsing infinite loop
mujacica Jan 20, 2026
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
64 changes: 64 additions & 0 deletions .github/workflows/e2e-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: E2E Integration Tests

on:
push:
branches:
- master
- "release/**"
pull_request:

concurrency:
group: e2e-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
e2e-test:
name: E2E Test (${{ matrix.os }})
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
cmake_generator: "Unix Makefiles"
- os: windows-latest
cmake_generator: "Visual Studio 17 2022"
- os: macos-latest
cmake_generator: "Unix Makefiles"

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Install dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt update
sudo apt install -y cmake libcurl4-openssl-dev

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install test dependencies
run: pip install -r tests/requirements.txt

- name: Add hosts entry (Linux/macOS)
if: runner.os != 'Windows'
run: sudo sh -c 'echo "127.0.0.1 sentry.native.test" >> /etc/hosts'

- name: Add hosts entry (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: Add-Content C:\Windows\System32\drivers\etc\hosts "127.0.0.1 sentry.native.test"

- name: Run E2E tests
env:
SENTRY_E2E_DSN: ${{ secrets.SENTRY_E2E_DSN }}
SENTRY_E2E_AUTH_TOKEN: ${{ secrets.SENTRY_E2E_AUTH_TOKEN }}
SENTRY_E2E_ORG: ${{ secrets.SENTRY_E2E_ORG }}
SENTRY_E2E_PROJECT: ${{ secrets.SENTRY_E2E_PROJECT }}
run: pytest --capture=no --verbose tests/test_e2e_sentry.py
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**:

- Add new `native` crash handling backend as an alternative to `crashpad`, `breakpad`, and `inproc`. This backend uses an out-of-process daemon that monitors the application for crashes, generates minidumps, and sends crash reports to Sentry. It supports Linux, macOS, and Windows, and is fully compatible with TSAN and ASAN sanitizers. ([#1433](https://github.com/getsentry/sentry-native/pull/1433))

**Fixes**:

- Crashpad: namespace mpack to avoid ODR violation. ([#1476](https://github.com/getsentry/sentry-native/pull/1476), [crashpad#143](https://github.com/getsentry/crashpad/pull/143))
Expand Down
105 changes: 103 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ else()
cmake_policy(SET CMP0077 NEW)
endif()

# Allow target_link_libraries() in subdirectories
if(POLICY CMP0079)
cmake_policy(SET CMP0079 NEW)
endif()

# Allow downstream SDKs to override the SDK version at CMake configuration time
set(SENTRY_SDK_VERSION "" CACHE STRING "Override the SDK version (supports full semver format with build metadata)")

Expand Down Expand Up @@ -219,9 +224,12 @@ else()
set(SENTRY_DEFAULT_BACKEND "inproc")
endif()

# Native backend is available on all platforms as an alternative
# It's lightweight (~5K LOC) and supports all platforms

if(NOT DEFINED SENTRY_BACKEND)
set(SENTRY_BACKEND ${SENTRY_DEFAULT_BACKEND} CACHE STRING
"The sentry backend responsible for reporting crashes, can be either 'none', 'inproc', 'breakpad' or 'crashpad'.")
"The sentry backend responsible for reporting crashes, can be either 'none', 'inproc', 'breakpad', 'crashpad', or 'native'.")
endif()

if(SENTRY_BACKEND STREQUAL "crashpad")
Expand All @@ -230,14 +238,16 @@ elseif(SENTRY_BACKEND STREQUAL "inproc")
set(SENTRY_BACKEND_INPROC TRUE)
elseif(SENTRY_BACKEND STREQUAL "breakpad")
set(SENTRY_BACKEND_BREAKPAD TRUE)
elseif(SENTRY_BACKEND STREQUAL "native")
set(SENTRY_BACKEND_NATIVE TRUE)
elseif(SENTRY_BACKEND STREQUAL "none")
set(SENTRY_BACKEND_NONE TRUE)
elseif(SENTRY_BACKEND STREQUAL "custom")
message(DEBUG
"SENTRY_BACKEND set to 'custom' - a custom backend source must be added to the compilation unit by the downstream SDK.")
else()
message(FATAL_ERROR
"SENTRY_BACKEND must be one of 'crashpad', 'inproc', 'breakpad' or 'none'.
"SENTRY_BACKEND must be one of 'crashpad', 'inproc', 'breakpad', 'native', or 'none'.
Downstream SDKs may choose to provide their own by specifying 'custom'.")
endif()

Expand Down Expand Up @@ -729,6 +739,97 @@ elseif(SENTRY_BACKEND_BREAKPAD)
endif()
elseif(SENTRY_BACKEND_INPROC)
target_compile_definitions(sentry PRIVATE SENTRY_WITH_INPROC_BACKEND)
elseif(SENTRY_BACKEND_NATIVE)
target_compile_definitions(sentry PRIVATE SENTRY_WITH_NATIVE_BACKEND)

# Native backend sources and configuration are in src/CMakeLists.txt
# The native backend requires C11 for atomics (set in src/CMakeLists.txt)

# Build sentry-crash executable for native backend
# Get all sources that were added to sentry target
get_target_property(SENTRY_SOURCES sentry SOURCES)

# Create daemon executable with same sources plus daemon-specific files
add_executable(sentry-crash
${SENTRY_SOURCES}
src/backends/native/sentry_crash_daemon.c
src/backends/native/sentry_crash_ipc.c
src/backends/native/sentry_crash_context.h
)

# Define standalone mode and copy compile definitions from sentry
target_compile_definitions(sentry-crash PRIVATE
SENTRY_CRASH_DAEMON_STANDALONE
SENTRY_BUILD_STATIC
SENTRY_HANDLER_STACK_SIZE=${SENTRY_HANDLER_STACK_SIZE}
)

# Windows-specific compile definitions
if(WIN32)
target_compile_definitions(sentry-crash PRIVATE
SENTRY_THREAD_STACK_GUARANTEE_FACTOR=${SENTRY_THREAD_STACK_GUARANTEE_FACTOR}
)
endif()

# Copy include directories from sentry target
target_include_directories(sentry-crash PRIVATE
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/src/backends/native
)

# Link same libraries as sentry
if(WIN32)
target_link_libraries(sentry-crash PRIVATE dbghelp shlwapi version)
elseif(LINUX OR ANDROID)
target_link_libraries(sentry-crash PRIVATE pthread rt dl)
elseif(APPLE)
find_library(COREFOUNDATION_LIBRARY CoreFoundation REQUIRED)
find_library(SECURITY_LIBRARY Security REQUIRED)
target_link_libraries(sentry-crash PRIVATE
${COREFOUNDATION_LIBRARY}
${SECURITY_LIBRARY}
)
endif()

# Transport-specific libraries
if(SENTRY_TRANSPORT_CURL)
target_link_libraries(sentry-crash PRIVATE CURL::libcurl)
endif()

if(SENTRY_TRANSPORT_WINHTTP)
target_link_libraries(sentry-crash PRIVATE winhttp)
endif()


# Compression library
if(SENTRY_TRANSPORT_COMPRESSION)
target_link_libraries(sentry-crash PRIVATE ZLIB::ZLIB)
endif()

# Unwinder libraries (must match sentry target)
if(SENTRY_WITH_LIBUNWINDSTACK)
target_link_libraries(sentry-crash PRIVATE unwindstack)
endif()

if(SENTRY_WITH_LIBUNWIND)
target_include_directories(sentry-crash PRIVATE ${LIBUNWIND_INCLUDE_DIR})
target_link_libraries(sentry-crash PRIVATE ${LIBUNWIND_LIBRARIES})
endif()

# Make sentry library depend on crash daemon so it's always built together
add_dependencies(sentry sentry-crash)

# Install daemon
install(TARGETS sentry-crash
RUNTIME DESTINATION bin
)

if(DEFINED SENTRY_FOLDER)
# Native backend doesn't have separate targets to organize
endif()

message(STATUS "Sentry crash daemon executable: enabled")
endif()

option(SENTRY_INTEGRATION_QT "Build Qt integration")
Expand Down
57 changes: 57 additions & 0 deletions examples/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,17 @@ has_arg(int argc, char **argv, const char *arg)
return false;
}

static const char *
get_arg_value(int argc, char **argv, const char *arg)
{
for (int i = 1; i < argc - 1; i++) {
if (strcmp(argv[i], arg) == 0) {
return argv[i + 1];
}
}
return NULL;
}

#if defined(SENTRY_PLATFORM_WINDOWS) && !defined(__MINGW32__) \
&& !defined(__MINGW64__)

Expand Down Expand Up @@ -279,10 +290,25 @@ static void *invalid_mem = (void *)0xFFFFFFFFFFFFFF9B; // -100 for memset
static void *invalid_mem = (void *)1;
#endif

// Detect Address Sanitizer (works for both GCC and Clang)
#if defined(__SANITIZE_ADDRESS__)
# define SENTRY_ASAN_ACTIVE 1
#elif defined(__has_feature)
# if __has_feature(address_sanitizer)
# define SENTRY_ASAN_ACTIVE 1
# endif
#endif

static void
trigger_crash()
{
#ifdef SENTRY_ASAN_ACTIVE
// Under ASAN, raise signal directly to bypass ASAN's memory interception.
// ASAN intercepts memset and would abort before our signal handler runs.
raise(SIGSEGV);
#else
memset((char *)invalid_mem, 1, 100);
#endif
}

static void
Expand Down Expand Up @@ -504,10 +530,41 @@ main(int argc, char **argv)
sentry_options_set_logs_with_attributes(options, true);
}

if (has_arg(argc, argv, "crash-mode")) {
const char *mode = get_arg_value(argc, argv, "crash-mode");
if (mode != NULL) {
if (strcmp(mode, "minidump") == 0) {
sentry_options_set_crash_reporting_mode(
options, SENTRY_CRASH_REPORTING_MODE_MINIDUMP);
} else if (strcmp(mode, "native") == 0) {
sentry_options_set_crash_reporting_mode(
options, SENTRY_CRASH_REPORTING_MODE_NATIVE);
} else if (strcmp(mode, "native-with-minidump") == 0) {
sentry_options_set_crash_reporting_mode(
options, SENTRY_CRASH_REPORTING_MODE_NATIVE_WITH_MINIDUMP);
}
}
}

// E2E test mode: generate unique test ID for event correlation
char e2e_test_id[37] = { 0 };
if (has_arg(argc, argv, "e2e-test")) {
sentry_uuid_t test_uuid = sentry_uuid_new_v4();
sentry_uuid_as_string(&test_uuid, e2e_test_id);
}

if (0 != sentry_init(options)) {
return EXIT_FAILURE;
}

// E2E test mode: set tags and output test ID for event correlation
if (e2e_test_id[0] != '\0') {
sentry_set_tag("test.id", e2e_test_id);
sentry_set_tag("test.suite", "e2e");
printf("TEST_ID:%s\n", e2e_test_id);
fflush(stdout);
}

if (has_arg(argc, argv, "log-attributes")) {
sentry_value_t attributes = sentry_value_new_object();
sentry_value_t attr = sentry_value_new_attribute(
Expand Down
Loading
Loading