Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

**Features**:

- Windows: report WINE runtime and host metadata in a separate `wine` context. ([#1004](https://github.com/getsentry/sentry-native/issues/1004))
- Native/Windows: capture WER report ID and expose as `contexts.wer.report_id` in crash events when the WER integration is enabled. ([#1970](https://github.com/getsentry/sentry-native/pull/1970))
- Add `sentry_set_tags` and `sentry_scope_set_tags` for updating multiple tags with a single scope flush, improving bulk-update performance. ([#1993](https://github.com/getsentry/sentry-native/pull/1993))
- Add `sentry_get_last_event_id` and `sentry_scope_get_last_event_id` for retrieving the last event ID captured with the global or given scope, respectively. ([#1992](https://github.com/getsentry/sentry-native/pull/1992))
Expand Down
65 changes: 65 additions & 0 deletions src/sentry_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,71 @@ sentry__get_windows_version(windows_version_t *win_ver)
return 1;
}

static void
set_wine_context_string(
sentry_value_t context, const char *key, const char *value)
{
if (value && value[0]) {
sentry_value_set_by_key(context, key, sentry_value_new_string(value));
}
}

sentry_value_t
sentry__make_wine_context(sentry__wine_get_version_t wine_get_version,
sentry__wine_get_build_id_t wine_get_build_id,
sentry__wine_get_host_version_t wine_get_host_version)
{
if (!wine_get_version) {
return sentry_value_new_null();
}

const char *version = wine_get_version();
if (!version || !version[0]) {
return sentry_value_new_null();
}

sentry_value_t context = sentry_value_new_object();
if (sentry_value_is_null(context)) {
return context;
}

set_wine_context_string(context, "version", version);
if (wine_get_build_id) {
set_wine_context_string(context, "build", wine_get_build_id());
}
if (wine_get_host_version) {
const char *sysname = NULL;
const char *release = NULL;
wine_get_host_version(&sysname, &release);
set_wine_context_string(context, "sysname", sysname);
set_wine_context_string(context, "release", release);
}

sentry_value_freeze(context);
return context;
}

sentry_value_t
sentry__get_wine_context(void)
{
const HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
if (!ntdll) {
return sentry_value_new_null();
}

const sentry__wine_get_version_t wine_get_version
= (sentry__wine_get_version_t)GetProcAddress(ntdll, "wine_get_version");
const sentry__wine_get_build_id_t wine_get_build_id
= (sentry__wine_get_build_id_t)GetProcAddress(
ntdll, "wine_get_build_id");
const sentry__wine_get_host_version_t wine_get_host_version
= (sentry__wine_get_host_version_t)GetProcAddress(
ntdll, "wine_get_host_version");

return sentry__make_wine_context(
wine_get_version, wine_get_build_id, wine_get_host_version);
}

# endif // !defined(SENTRY_PLATFORM_XBOX)

sentry_value_t
Expand Down
14 changes: 14 additions & 0 deletions src/sentry_os.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ typedef struct {

int sentry__get_kernel_version(windows_version_t *win_ver);
int sentry__get_windows_version(windows_version_t *win_ver);

# if !defined(SENTRY_PLATFORM_XBOX)
typedef const char *(CDECL *sentry__wine_get_version_t)(void);
typedef const char *(CDECL *sentry__wine_get_build_id_t)(void);
typedef void(CDECL *sentry__wine_get_host_version_t)(
const char **sysname, const char **release);

sentry_value_t sentry__make_wine_context(
sentry__wine_get_version_t wine_get_version,
sentry__wine_get_build_id_t wine_get_build_id,
sentry__wine_get_host_version_t wine_get_host_version);
sentry_value_t sentry__get_wine_context(void);
# endif

void sentry__set_default_thread_stack_guarantee(void);
void sentry__init_cached_kernel32_functions(void);
void sentry__get_system_time(LPFILETIME filetime);
Expand Down
8 changes: 8 additions & 0 deletions src/sentry_scope.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ get_scope(void)
init_scope(&g_scope);
g_scope.user = sentry_value_new_object();
sentry_value_set_by_key(g_scope.contexts, "os", sentry__get_os_context());
#if defined(SENTRY_PLATFORM_WINDOWS) && !defined(SENTRY_PLATFORM_XBOX)
sentry_value_t wine_context = sentry__get_wine_context();
if (!sentry_value_is_null(wine_context)) {
sentry_value_set_by_key(g_scope.contexts, "wine", wine_context);
} else {
sentry_value_decref(wine_context);
}
#endif
g_scope.client_sdk = get_client_sdk();

g_scope_initialized = true;
Expand Down
69 changes: 69 additions & 0 deletions tests/unit/test_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,33 @@ extern void(WINAPI *g_kernel32_GetCurrentThreadStackLimits)(
PULONG_PTR, PULONG_PTR);
static size_t g_kernel32_SetThreadStackGuaranteeCalled = 0;

# if !defined(SENTRY_PLATFORM_XBOX)
static const char *CDECL
wine_get_version(void)
{
return "9.0";
}

static const char *CDECL
wine_get_empty_version(void)
{
return "";
}

static const char *CDECL
wine_get_build_id(void)
{
return "wine-9.0";
}

static void CDECL
wine_get_host_version(const char **sysname, const char **release)
{
*sysname = "Linux";
*release = "6.8.0";
}
# endif

static BOOL WINAPI
no_previous_guarantee(PULONG guarantee)
{
Expand Down Expand Up @@ -295,6 +322,48 @@ stack_reserve_exact_factor_minus_one(PULONG_PTR low, PULONG_PTR high)
}
#endif

SENTRY_TEST(wine_context)
{
#if !defined(SENTRY_PLATFORM_WINDOWS) || defined(SENTRY_PLATFORM_XBOX)
SKIP_TEST();
#else
sentry_value_t context = sentry__make_wine_context(
wine_get_version, wine_get_build_id, wine_get_host_version);
TEST_CHECK(!sentry_value_is_null(context));
TEST_CHECK(sentry_value_is_frozen(context));
TEST_CHECK_STRING_EQUAL(
sentry_value_as_string(sentry_value_get_by_key(context, "version")),
"9.0");
TEST_CHECK_STRING_EQUAL(
sentry_value_as_string(sentry_value_get_by_key(context, "build")),
"wine-9.0");
TEST_CHECK_STRING_EQUAL(
sentry_value_as_string(sentry_value_get_by_key(context, "sysname")),
"Linux");
TEST_CHECK_STRING_EQUAL(
sentry_value_as_string(sentry_value_get_by_key(context, "release")),
"6.8.0");
sentry_value_decref(context);

context = sentry__make_wine_context(wine_get_version, NULL, NULL);
TEST_CHECK(!sentry_value_is_null(context));
TEST_CHECK(sentry_value_is_null(sentry_value_get_by_key(context, "build")));
TEST_CHECK(
sentry_value_is_null(sentry_value_get_by_key(context, "sysname")));
TEST_CHECK(
sentry_value_is_null(sentry_value_get_by_key(context, "release")));
sentry_value_decref(context);

context = sentry__make_wine_context(NULL, NULL, NULL);
TEST_CHECK(sentry_value_is_null(context));
sentry_value_decref(context);

context = sentry__make_wine_context(wine_get_empty_version, NULL, NULL);
TEST_CHECK(sentry_value_is_null(context));
sentry_value_decref(context);
#endif
}

SENTRY_TEST(stack_guarantee)
{
#if !defined(SENTRY_PLATFORM_WINDOWS)
Expand Down
1 change: 1 addition & 0 deletions tests/unit/tests.inc
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ XX(value_uint64)
XX(value_unicode)
XX(value_user)
XX(value_wrong_type)
XX(wine_context)
XX(write_envelope_partial_write_fails)
XX(write_raw_envelope_to_file)
XX(writer_byte_count_stops_after_failure)
Expand Down