Skip to content

Commit 5596cbb

Browse files
authored
build: remove obsolete CRASHPAD_WER_ENABLED (#950)
* build: remove obsolete CRASHPAD_WER_ENABLED we initially introduced the build flag because of a potentially missing struct member if an older target version than 19041 was selected in a build: getsentry/crashpad#70 But upstream fixed that with a local compatibility struct a while ago: https://chromium.googlesource.com/crashpad/crashpad/+/ca928c8d6b651b7123f1a5cad36dba08ca2416bc That means we can get rid of the build-flag entirely, because this will build on all supported platforms and add a runtime version check for `build == 19041`, so that we don't even register the module (including not polluting the registry) on WER versions that don't support fast-fail crashes .
1 parent 9ea6090 commit 5596cbb

File tree

7 files changed

+157
-99
lines changed

7 files changed

+157
-99
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
**Internal**:
6+
7+
- Remove the `CRASHPAD_WER_ENABLED` build flag. The WER module is now built for all supported Windows targets, and registration is conditional on runtime Windows version checks. ([#950](https://github.com/getsentry/sentry-native/pull/950), [crashpad#96](https://github.com/getsentry/crashpad/pull/96))
8+
39
## 0.7.0
410

511
**Breaking changes**:

CMakeLists.txt

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ if(SENTRY_BACKEND_CRASHPAD)
423423
endif()
424424
add_subdirectory(external/crashpad crashpad_build)
425425

426-
if(CRASHPAD_WER_ENABLED)
426+
if(WIN32)
427427
add_dependencies(sentry crashpad::wer)
428428
endif()
429429

@@ -438,9 +438,7 @@ if(SENTRY_BACKEND_CRASHPAD)
438438
set_property(TARGET crashpad_snapshot PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
439439
set_property(TARGET crashpad_tools PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
440440
set_property(TARGET crashpad_util PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
441-
if(CRASHPAD_WER_ENABLED)
442-
set_property(TARGET crashpad_wer PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
443-
endif()
441+
set_property(TARGET crashpad_wer PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
444442
set_property(TARGET crashpad_zlib PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
445443
set_property(TARGET mini_chromium PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
446444
endif()
@@ -457,9 +455,7 @@ if(SENTRY_BACKEND_CRASHPAD)
457455
set_target_properties(crashpad_util PROPERTIES FOLDER ${SENTRY_FOLDER})
458456
set_target_properties(crashpad_zlib PROPERTIES FOLDER ${SENTRY_FOLDER})
459457
set_target_properties(mini_chromium PROPERTIES FOLDER ${SENTRY_FOLDER})
460-
if(CRASHPAD_WER_ENABLED)
461-
set_target_properties(crashpad_wer PROPERTIES FOLDER ${SENTRY_FOLDER})
462-
endif()
458+
set_target_properties(crashpad_wer PROPERTIES FOLDER ${SENTRY_FOLDER})
463459
endif()
464460

465461
target_link_libraries(sentry PRIVATE
@@ -472,16 +468,10 @@ if(SENTRY_BACKEND_CRASHPAD)
472468
if(WIN32 AND MSVC)
473469
sentry_install(FILES $<TARGET_PDB_FILE:crashpad_handler>
474470
DESTINATION "${CMAKE_INSTALL_BINDIR}" OPTIONAL)
475-
if (CRASHPAD_WER_ENABLED)
476-
sentry_install(FILES $<TARGET_PDB_FILE:crashpad_wer>
477-
DESTINATION "${CMAKE_INSTALL_BINDIR}" OPTIONAL)
478-
endif()
471+
sentry_install(FILES $<TARGET_PDB_FILE:crashpad_wer>
472+
DESTINATION "${CMAKE_INSTALL_BINDIR}" OPTIONAL)
479473
endif()
480474
add_dependencies(sentry crashpad::handler)
481-
482-
if(CRASHPAD_WER_ENABLED)
483-
add_compile_definitions(CRASHPAD_WER_ENABLED)
484-
endif()
485475
elseif(SENTRY_BACKEND_BREAKPAD)
486476
option(SENTRY_BREAKPAD_SYSTEM "Use system breakpad" OFF)
487477
if(SENTRY_BREAKPAD_SYSTEM)
@@ -575,10 +565,9 @@ if(SENTRY_BUILD_EXAMPLES)
575565

576566
if(MSVC)
577567
target_compile_options(sentry_example PRIVATE $<BUILD_INTERFACE:/wd5105>)
578-
if(CRASHPAD_WER_ENABLED)
579-
# to test handling SEH by-passing exceptions we need to enable the control flow guard
580-
target_compile_options(sentry_example PRIVATE $<BUILD_INTERFACE:/guard:cf>)
581-
endif()
568+
569+
# to test handling SEH by-passing exceptions we need to enable the control flow guard
570+
target_compile_options(sentry_example PRIVATE $<BUILD_INTERFACE:/guard:cf>)
582571
endif()
583572

584573
# set static runtime if enabled

examples/example.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ has_arg(int argc, char **argv, const char *arg)
9393
return false;
9494
}
9595

96-
#ifdef CRASHPAD_WER_ENABLED
96+
#if defined(SENTRY_PLATFORM_WINDOWS) && !defined(__MINGW32__) \
97+
&& !defined(__MINGW64__)
98+
9799
int
98100
call_rffe_many_times()
99101
{
@@ -138,7 +140,7 @@ trigger_fastfail_crash()
138140
__fastfail(77);
139141
}
140142

141-
#endif // CRASHPAD_WER_ENABLED
143+
#endif
142144

143145
#ifdef SENTRY_PLATFORM_AIX
144146
// AIX has a null page mapped to the bottom of memory, which means null derefs
@@ -301,7 +303,8 @@ main(int argc, char **argv)
301303
if (has_arg(argc, argv, "crash")) {
302304
trigger_crash();
303305
}
304-
#ifdef CRASHPAD_WER_ENABLED
306+
#if defined(SENTRY_PLATFORM_WINDOWS) && !defined(__MINGW32__) \
307+
&& !defined(__MINGW64__)
305308
if (has_arg(argc, argv, "fastfail")) {
306309
trigger_fastfail_crash();
307310
}

external/crashpad

src/backends/sentry_backend_crashpad.cpp

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ extern "C" {
77
#include "sentry_database.h"
88
#include "sentry_envelope.h"
99
#include "sentry_options.h"
10+
#ifdef SENTRY_PLATFORM_WINDOWS
11+
# include "sentry_os.h"
12+
#endif
1013
#include "sentry_path.h"
1114
#include "sentry_sync.h"
1215
#include "sentry_transport.h"
13-
#include "sentry_unix_pageallocator.h"
16+
#ifdef SENTRY_PLATFORM_LINUX
17+
# include "sentry_unix_pageallocator.h"
18+
#endif
1419
#include "sentry_utils.h"
1520
#include "transports/sentry_disk_transport.h"
1621
}
@@ -110,6 +115,51 @@ crashpad_backend_user_consent_changed(sentry_backend_t *backend)
110115
data->db->GetSettings()->SetUploadsEnabled(!sentry__should_skip_upload());
111116
}
112117

118+
#ifdef SENTRY_PLATFORM_WINDOWS
119+
static void
120+
crashpad_register_wer_module(
121+
const sentry_path_t *absolute_handler_path, const crashpad_state_t *data)
122+
{
123+
windows_version_t win_ver;
124+
if (!sentry__get_windows_version(&win_ver) || win_ver.build < 19041) {
125+
SENTRY_WARN("Crashpad WER module not registered, because Windows "
126+
"doesn't meet version requirements (build >= 19041).");
127+
return;
128+
}
129+
sentry_path_t *handler_dir = sentry__path_dir(absolute_handler_path);
130+
sentry_path_t *wer_path = nullptr;
131+
if (handler_dir) {
132+
wer_path = sentry__path_join_str(handler_dir, "crashpad_wer.dll");
133+
sentry__path_free(handler_dir);
134+
}
135+
136+
if (wer_path && sentry__path_is_file(wer_path)) {
137+
SENTRY_TRACEF("registering crashpad WER handler "
138+
"\"%" SENTRY_PATH_PRI "\"",
139+
wer_path->path);
140+
141+
// The WER handler needs to be registered in the registry first.
142+
constexpr DWORD dwOne = 1;
143+
const LSTATUS reg_res = RegSetKeyValueW(HKEY_CURRENT_USER,
144+
L"Software\\Microsoft\\Windows\\Windows Error Reporting\\"
145+
L"RuntimeExceptionHelperModules",
146+
wer_path->path, REG_DWORD, &dwOne, sizeof(DWORD));
147+
if (reg_res != ERROR_SUCCESS) {
148+
SENTRY_WARN("registering crashpad WER handler in registry failed");
149+
} else {
150+
const std::wstring wer_path_string(wer_path->path);
151+
if (!data->client->RegisterWerModule(wer_path_string)) {
152+
SENTRY_WARN("registering crashpad WER handler module failed");
153+
}
154+
}
155+
156+
sentry__path_free(wer_path);
157+
} else {
158+
SENTRY_WARN("crashpad WER handler module not found");
159+
}
160+
}
161+
#endif
162+
113163
static void
114164
crashpad_backend_flush_scope(
115165
sentry_backend_t *backend, const sentry_options_t *options)
@@ -363,39 +413,9 @@ crashpad_backend_startup(
363413
return 1;
364414
}
365415

366-
#ifdef CRASHPAD_WER_ENABLED
367-
sentry_path_t *handler_dir = sentry__path_dir(absolute_handler_path);
368-
sentry_path_t *wer_path = nullptr;
369-
if (handler_dir) {
370-
wer_path = sentry__path_join_str(handler_dir, "crashpad_wer.dll");
371-
sentry__path_free(handler_dir);
372-
}
373-
374-
if (wer_path && sentry__path_is_file(wer_path)) {
375-
SENTRY_TRACEF("registering crashpad WER handler "
376-
"\"%" SENTRY_PATH_PRI "\"",
377-
wer_path->path);
378-
379-
// The WER handler needs to be registered in the registry first.
380-
DWORD dwOne = 1;
381-
LSTATUS reg_res = RegSetKeyValueW(HKEY_CURRENT_USER,
382-
L"Software\\Microsoft\\Windows\\Windows Error Reporting\\"
383-
L"RuntimeExceptionHelperModules",
384-
wer_path->path, REG_DWORD, &dwOne, sizeof(DWORD));
385-
if (reg_res != ERROR_SUCCESS) {
386-
SENTRY_WARN("registering crashpad WER handler in registry failed");
387-
} else {
388-
std::wstring wer_path_string(wer_path->path);
389-
if (!data->client->RegisterWerModule(wer_path_string)) {
390-
SENTRY_WARN("registering crashpad WER handler module failed");
391-
}
392-
}
393-
394-
sentry__path_free(wer_path);
395-
} else {
396-
SENTRY_WARN("crashpad WER handler module not found");
397-
}
398-
#endif // CRASHPAD_WER_ENABLED
416+
#ifdef SENTRY_PLATFORM_WINDOWS
417+
crashpad_register_wer_module(absolute_handler_path, data);
418+
#endif
399419

400420
sentry__path_free(absolute_handler_path);
401421

src/sentry_os.c

Lines changed: 70 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
# define CURRENT_VERSION "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
99

1010
void *
11-
sentry__try_file_version(LPCWSTR filename)
11+
sentry__try_file_version(const LPCWSTR filename)
1212
{
13-
14-
DWORD size = GetFileVersionInfoSizeW(filename, NULL);
13+
const DWORD size = GetFileVersionInfoSizeW(filename, NULL);
1514
if (!size) {
1615
return NULL;
1716
}
@@ -24,86 +23,115 @@ sentry__try_file_version(LPCWSTR filename)
2423
return ffibuf;
2524
}
2625

27-
sentry_value_t
28-
sentry__get_os_context(void)
26+
int
27+
sentry__get_kernel_version(windows_version_t *win_ver)
2928
{
30-
sentry_value_t os = sentry_value_new_object();
31-
if (sentry_value_is_null(os)) {
32-
return os;
33-
}
34-
35-
sentry_value_set_by_key(os, "name", sentry_value_new_string("Windows"));
36-
3729
void *ffibuf = sentry__try_file_version(L"ntoskrnl.exe");
3830
if (!ffibuf) {
3931
ffibuf = sentry__try_file_version(L"kernel32.dll");
4032
}
4133
if (!ffibuf) {
42-
goto fail;
34+
return 0;
4335
}
4436

4537
VS_FIXEDFILEINFO *ffi;
4638
UINT ffi_size;
47-
if (!VerQueryValueW(ffibuf, L"\\", &ffi, &ffi_size)) {
48-
goto fail;
39+
if (!VerQueryValueW(ffibuf, L"\\", (LPVOID *)&ffi, &ffi_size)) {
40+
sentry_free(ffibuf);
41+
return 0;
4942
}
5043
ffi->dwFileFlags &= ffi->dwFileFlagsMask;
5144

52-
uint32_t major_version = ffi->dwFileVersionMS >> 16;
53-
uint32_t minor_version = ffi->dwFileVersionMS & 0xffff;
54-
uint32_t build_version = ffi->dwFileVersionLS >> 16;
55-
uint32_t ubr = ffi->dwFileVersionLS & 0xffff;
56-
57-
char buf[32];
58-
snprintf(buf, sizeof(buf), "%u.%u.%u.%lu", major_version, minor_version,
59-
build_version, ubr);
60-
sentry_value_set_by_key(os, "kernel_version", sentry_value_new_string(buf));
45+
win_ver->major = ffi->dwFileVersionMS >> 16;
46+
win_ver->minor = ffi->dwFileVersionMS & 0xffff;
47+
win_ver->build = ffi->dwFileVersionLS >> 16;
48+
win_ver->ubr = ffi->dwFileVersionLS & 0xffff;
6149

6250
sentry_free(ffibuf);
6351

52+
return 1;
53+
}
54+
55+
int
56+
sentry__get_windows_version(windows_version_t *win_ver)
57+
{
6458
// The `CurrentMajorVersionNumber`, `CurrentMinorVersionNumber` and `UBR`
6559
// are DWORD, while `CurrentBuild` is a SZ (text).
66-
6760
uint32_t reg_version = 0;
6861
DWORD buf_size = sizeof(uint32_t);
6962
if (RegGetValueA(HKEY_LOCAL_MACHINE, CURRENT_VERSION,
7063
"CurrentMajorVersionNumber", RRF_RT_REG_DWORD, NULL, &reg_version,
7164
&buf_size)
72-
== ERROR_SUCCESS) {
73-
major_version = reg_version;
65+
!= ERROR_SUCCESS) {
66+
return 0;
7467
}
68+
win_ver->major = reg_version;
69+
7570
buf_size = sizeof(uint32_t);
7671
if (RegGetValueA(HKEY_LOCAL_MACHINE, CURRENT_VERSION,
7772
"CurrentMinorVersionNumber", RRF_RT_REG_DWORD, NULL, &reg_version,
7873
&buf_size)
79-
== ERROR_SUCCESS) {
80-
minor_version = reg_version;
74+
!= ERROR_SUCCESS) {
75+
return 0;
8176
}
77+
win_ver->minor = reg_version;
78+
79+
char buf[32];
8280
buf_size = sizeof(buf);
8381
if (RegGetValueA(HKEY_LOCAL_MACHINE, CURRENT_VERSION, "CurrentBuild",
8482
RRF_RT_REG_SZ, NULL, buf, &buf_size)
85-
== ERROR_SUCCESS) {
86-
build_version = (uint32_t)sentry__strtod_c(buf, NULL);
83+
!= ERROR_SUCCESS) {
84+
return 0;
8785
}
86+
win_ver->build = (uint32_t)sentry__strtod_c(buf, NULL);
87+
8888
buf_size = sizeof(uint32_t);
8989
if (RegGetValueA(HKEY_LOCAL_MACHINE, CURRENT_VERSION, "UBR",
9090
RRF_RT_REG_DWORD, NULL, &reg_version, &buf_size)
91-
== ERROR_SUCCESS) {
92-
ubr = reg_version;
91+
!= ERROR_SUCCESS) {
92+
return 0;
9393
}
94+
win_ver->ubr = reg_version;
9495

95-
snprintf(buf, sizeof(buf), "%u.%u.%u", major_version, minor_version,
96-
build_version);
97-
sentry_value_set_by_key(os, "version", sentry_value_new_string(buf));
96+
return 1;
97+
}
9898

99-
snprintf(buf, sizeof(buf), "%lu", ubr);
100-
sentry_value_set_by_key(os, "build", sentry_value_new_string(buf));
99+
sentry_value_t
100+
sentry__get_os_context(void)
101+
{
102+
const sentry_value_t os = sentry_value_new_object();
103+
if (sentry_value_is_null(os)) {
104+
return os;
105+
}
106+
sentry_value_set_by_key(os, "name", sentry_value_new_string("Windows"));
101107

102-
sentry_value_freeze(os);
103-
return os;
108+
bool at_least_one_key_successful = false;
109+
char buf[32];
110+
windows_version_t win_ver;
111+
if (sentry__get_kernel_version(&win_ver)) {
112+
at_least_one_key_successful = true;
104113

105-
fail:
106-
sentry_free(ffibuf);
114+
snprintf(buf, sizeof(buf), "%u.%u.%u.%lu", win_ver.major, win_ver.minor,
115+
win_ver.build, win_ver.ubr);
116+
sentry_value_set_by_key(
117+
os, "kernel_version", sentry_value_new_string(buf));
118+
}
119+
120+
if (sentry__get_windows_version(&win_ver)) {
121+
at_least_one_key_successful = true;
122+
123+
snprintf(buf, sizeof(buf), "%u.%u.%u", win_ver.major, win_ver.minor,
124+
win_ver.build);
125+
sentry_value_set_by_key(os, "version", sentry_value_new_string(buf));
126+
127+
snprintf(buf, sizeof(buf), "%lu", win_ver.ubr);
128+
sentry_value_set_by_key(os, "build", sentry_value_new_string(buf));
129+
}
130+
131+
if (at_least_one_key_successful) {
132+
sentry_value_freeze(os);
133+
return os;
134+
}
107135

108136
sentry_value_decref(os);
109137
return sentry_value_new_null();

0 commit comments

Comments
 (0)