Skip to content

Commit 43e00a9

Browse files
authored
feat: thread context from breakpad on macos (#1083)
* feat: provide the thread-context to the [on_crash|before_send]-hooks on macOS from the breakpad backend. * Get rid of remaining static functions with `sentry__` prefix in the breakpad backend. * update `breakpad` submodule to our fork's `handler` branch
1 parent 2ad5f0d commit 43e00a9

File tree

5 files changed

+45
-26
lines changed

5 files changed

+45
-26
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
**Features**:
66

77
- Android NDK: Add `.loadNativeLibraries()` method to allow pre-loading .so files ([#1082](https://github.com/getsentry/sentry-native/pull/1082))
8+
- Fill the `ucontext_t` field in the `sentry_ucontext_t` `[on_crash|before_send]`-hook parameter on `macOS` from the `breakpad` backend. ([#1083](https://github.com/getsentry/sentry-native/pull/1083), [breakpad#39](https://github.com/getsentry/breakpad/pull/39))
9+
10+
**Thank you**:
11+
12+
[saf-e](https://github.com/saf-e)
813

914
## 0.7.13
1015

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ if(SENTRY_BACKEND_CRASHPAD)
479479
elseif(SENTRY_BACKEND_BREAKPAD)
480480
option(SENTRY_BREAKPAD_SYSTEM "Use system breakpad" OFF)
481481
if(SENTRY_BREAKPAD_SYSTEM)
482+
target_compile_definitions(sentry PRIVATE SENTRY_BREAKPAD_SYSTEM)
482483
# system breakpad is using pkg-config, see `external/breakpad/breakpad-client.pc.in`
483484
find_package(PkgConfig REQUIRED)
484485
pkg_check_modules(BREAKPAD REQUIRED IMPORTED_TARGET breakpad-client)

external/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ add_library(breakpad_client STATIC)
128128
set_property(TARGET breakpad_client PROPERTY CXX_STANDARD 17)
129129
set_property(TARGET breakpad_client PROPERTY CXX_STANDARD_REQUIRED On)
130130
target_sources(breakpad_client PRIVATE ${BREAKPAD_SOURCES_COMMON})
131+
target_compile_definitions(breakpad_client PRIVATE SENTRY_BACKEND_BREAKPAD)
131132

132133
if(LINUX OR ANDROID)
133134
target_sources(breakpad_client PRIVATE ${BREAKPAD_SOURCES_COMMON_LINUX} ${BREAKPAD_SOURCES_CLIENT_LINUX})

src/backends/sentry_backend_breakpad.cpp

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ extern "C" {
2929
#elif defined(SENTRY_PLATFORM_MACOS)
3030
# include "client/mac/handler/exception_handler.h"
3131
# include <sys/sysctl.h>
32+
# include <unistd.h>
3233
#elif defined(SENTRY_PLATFORM_IOS)
3334
# include "client/ios/exception_handler_no_mach.h"
3435
#else
@@ -41,18 +42,24 @@ extern "C" {
4142

4243
#ifdef SENTRY_PLATFORM_WINDOWS
4344
static bool
44-
sentry__breakpad_backend_callback(const wchar_t *breakpad_dump_path,
45+
breakpad_backend_callback(const wchar_t *breakpad_dump_path,
4546
const wchar_t *minidump_id, void *UNUSED(context),
4647
EXCEPTION_POINTERS *exinfo, MDRawAssertionInfo *UNUSED(assertion),
4748
bool succeeded)
4849
#elif defined(SENTRY_PLATFORM_DARWIN)
50+
# ifdef SENTRY_BREAKPAD_SYSTEM
4951
static bool
50-
sentry__breakpad_backend_callback(const char *breakpad_dump_path,
52+
breakpad_backend_callback(const char *breakpad_dump_path,
5153
const char *minidump_id, void *UNUSED(context), bool succeeded)
54+
# else
55+
static bool
56+
breakpad_backend_callback(const char *breakpad_dump_path,
57+
const char *minidump_id, void *UNUSED(context),
58+
breakpad_ucontext_t *user_context, bool succeeded)
59+
# endif
5260
#else
5361
static bool
54-
sentry__breakpad_backend_callback(
55-
const google_breakpad::MinidumpDescriptor &descriptor,
62+
breakpad_backend_callback(const google_breakpad::MinidumpDescriptor &descriptor,
5663
void *UNUSED(context), bool succeeded)
5764
#endif
5865
{
@@ -106,6 +113,12 @@ sentry__breakpad_backend_callback(
106113
if (options->on_crash_func) {
107114
sentry_ucontext_t *uctx = nullptr;
108115

116+
#if defined(SENTRY_PLATFORM_DARWIN) && !defined(SENTRY_BREAKPAD_SYSTEM)
117+
sentry_ucontext_t uctx_data;
118+
uctx_data.user_context = user_context;
119+
uctx = &uctx_data;
120+
#endif
121+
109122
#ifdef SENTRY_PLATFORM_WINDOWS
110123
sentry_ucontext_t uctx_data;
111124
uctx_data.exception_ptrs = *exinfo;
@@ -206,49 +219,48 @@ IsDebuggerActive()
206219
#endif
207220

208221
static int
209-
sentry__breakpad_backend_startup(
222+
breakpad_backend_startup(
210223
sentry_backend_t *backend, const sentry_options_t *options)
211224
{
212225
sentry_path_t *current_run_folder = options->run->run_path;
213226

214227
#ifdef SENTRY_PLATFORM_WINDOWS
215228
sentry__reserve_thread_stack();
216229
backend->data = new google_breakpad::ExceptionHandler(
217-
current_run_folder->path, NULL, sentry__breakpad_backend_callback, NULL,
230+
current_run_folder->path, NULL, breakpad_backend_callback, NULL,
218231
google_breakpad::ExceptionHandler::HANDLER_EXCEPTION);
219232
#elif defined(SENTRY_PLATFORM_MACOS)
220233
// If process is being debugged and there are breakpoints set it will cause
221234
// task_set_exception_ports to crash the whole process and debugger
222-
backend->data
223-
= new google_breakpad::ExceptionHandler(current_run_folder->path, NULL,
224-
sentry__breakpad_backend_callback, NULL, !IsDebuggerActive(), NULL);
235+
backend->data = new google_breakpad::ExceptionHandler(
236+
current_run_folder->path, nullptr, breakpad_backend_callback, nullptr,
237+
!IsDebuggerActive(), nullptr);
225238
#elif defined(SENTRY_PLATFORM_IOS)
226239
backend->data
227-
= new google_breakpad::ExceptionHandler(current_run_folder->path, NULL,
228-
sentry__breakpad_backend_callback, NULL, true, NULL);
240+
= new google_breakpad::ExceptionHandler(current_run_folder->path,
241+
nullptr, breakpad_backend_callback, nullptr, true, nullptr);
229242
#else
230243
google_breakpad::MinidumpDescriptor descriptor(current_run_folder->path);
231244
backend->data = new google_breakpad::ExceptionHandler(
232-
descriptor, NULL, sentry__breakpad_backend_callback, NULL, true, -1);
245+
descriptor, nullptr, breakpad_backend_callback, nullptr, true, -1);
233246
#endif
234-
return backend->data == NULL;
247+
return backend->data == nullptr;
235248
}
236249

237250
static void
238-
sentry__breakpad_backend_shutdown(sentry_backend_t *backend)
251+
breakpad_backend_shutdown(sentry_backend_t *backend)
239252
{
240-
google_breakpad::ExceptionHandler *eh
241-
= (google_breakpad::ExceptionHandler *)backend->data;
242-
backend->data = NULL;
253+
const auto *eh
254+
= static_cast<google_breakpad::ExceptionHandler *>(backend->data);
255+
backend->data = nullptr;
243256
delete eh;
244257
}
245258

246259
static void
247-
sentry__breakpad_backend_except(
260+
breakpad_backend_except(
248261
sentry_backend_t *backend, const sentry_ucontext_t *context)
249262
{
250-
google_breakpad::ExceptionHandler *eh
251-
= (google_breakpad::ExceptionHandler *)backend->data;
263+
auto *eh = static_cast<google_breakpad::ExceptionHandler *>(backend->data);
252264

253265
#ifdef SENTRY_PLATFORM_WINDOWS
254266
eh->WriteMinidumpForException(
@@ -274,15 +286,15 @@ extern "C" {
274286
sentry_backend_t *
275287
sentry__backend_new(void)
276288
{
277-
sentry_backend_t *backend = SENTRY_MAKE(sentry_backend_t);
289+
auto *backend = SENTRY_MAKE(sentry_backend_t);
278290
if (!backend) {
279-
return NULL;
291+
return nullptr;
280292
}
281293
memset(backend, 0, sizeof(sentry_backend_t));
282294

283-
backend->startup_func = sentry__breakpad_backend_startup;
284-
backend->shutdown_func = sentry__breakpad_backend_shutdown;
285-
backend->except_func = sentry__breakpad_backend_except;
295+
backend->startup_func = breakpad_backend_startup;
296+
backend->shutdown_func = breakpad_backend_shutdown;
297+
backend->except_func = breakpad_backend_except;
286298

287299
return backend;
288300
}

0 commit comments

Comments
 (0)