From f02d495ee9d56265550532e06d7035556f35c5da Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 2 Mar 2026 10:19:46 +0100 Subject: [PATCH] ref: add SENTRY_MAKE_0 macro for zero-initialized allocation Introduce sentry__calloc and SENTRY_MAKE_0 to replace the recurring SENTRY_MAKE + memset(ptr, 0, sizeof(T)) pattern across the codebase. Co-Authored-By: Claude Opus 4.6 --- src/backends/native/sentry_crash_ipc.c | 18 ++++++------------ src/backends/sentry_backend_breakpad.cpp | 3 +-- src/backends/sentry_backend_crashpad.cpp | 3 +-- src/backends/sentry_backend_inproc.c | 3 +-- src/backends/sentry_backend_native.c | 7 ++----- src/sentry_alloc.c | 17 +++++++++++++++++ src/sentry_alloc.h | 6 ++++++ src/sentry_attachment.c | 9 +++------ src/sentry_batcher.c | 4 +--- src/sentry_hint.c | 3 +-- src/sentry_options.c | 3 +-- src/sentry_retry.c | 3 +-- src/sentry_scope.c | 4 ++-- src/sentry_sync.c | 7 ++----- src/sentry_transport.c | 3 +-- src/sentry_utils.c | 3 +-- src/sentry_value.c | 12 ++++-------- src/transports/sentry_http_transport.c | 3 +-- src/transports/sentry_http_transport_curl.c | 3 +-- src/transports/sentry_http_transport_winhttp.c | 3 +-- 20 files changed, 54 insertions(+), 63 deletions(-) diff --git a/src/backends/native/sentry_crash_ipc.c b/src/backends/native/sentry_crash_ipc.c index 35b13c40e7..74afcae77a 100644 --- a/src/backends/native/sentry_crash_ipc.c +++ b/src/backends/native/sentry_crash_ipc.c @@ -19,11 +19,10 @@ sentry_crash_ipc_t * sentry__crash_ipc_init_app(sem_t *init_sem) { - sentry_crash_ipc_t *ipc = SENTRY_MAKE(sentry_crash_ipc_t); + sentry_crash_ipc_t *ipc = SENTRY_MAKE_0(sentry_crash_ipc_t); if (!ipc) { return NULL; } - memset(ipc, 0, sizeof(sentry_crash_ipc_t)); ipc->is_daemon = false; ipc->init_sem = init_sem; // Use provided semaphore (managed by backend) @@ -175,11 +174,10 @@ sentry_crash_ipc_t * sentry__crash_ipc_init_daemon( pid_t app_pid, uint64_t app_tid, int notify_eventfd, int ready_eventfd) { - sentry_crash_ipc_t *ipc = SENTRY_MAKE(sentry_crash_ipc_t); + sentry_crash_ipc_t *ipc = SENTRY_MAKE_0(sentry_crash_ipc_t); if (!ipc) { return NULL; } - memset(ipc, 0, sizeof(sentry_crash_ipc_t)); ipc->is_daemon = true; // Open existing shared memory created by app (using PID and thread ID) @@ -312,11 +310,10 @@ sentry__crash_ipc_free(sentry_crash_ipc_t *ipc) sentry_crash_ipc_t * sentry__crash_ipc_init_app(sem_t *init_sem) { - sentry_crash_ipc_t *ipc = SENTRY_MAKE(sentry_crash_ipc_t); + sentry_crash_ipc_t *ipc = SENTRY_MAKE_0(sentry_crash_ipc_t); if (!ipc) { return NULL; } - memset(ipc, 0, sizeof(sentry_crash_ipc_t)); ipc->is_daemon = false; ipc->init_sem = init_sem; // Use provided semaphore (managed by backend) @@ -470,11 +467,10 @@ sentry_crash_ipc_t * sentry__crash_ipc_init_daemon( pid_t app_pid, uint64_t app_tid, int notify_pipe_read, int ready_pipe_write) { - sentry_crash_ipc_t *ipc = SENTRY_MAKE(sentry_crash_ipc_t); + sentry_crash_ipc_t *ipc = SENTRY_MAKE_0(sentry_crash_ipc_t); if (!ipc) { return NULL; } - memset(ipc, 0, sizeof(sentry_crash_ipc_t)); ipc->is_daemon = true; // Open existing shared memory created by app (using PID and thread ID) @@ -604,11 +600,10 @@ sentry__crash_ipc_free(sentry_crash_ipc_t *ipc) sentry_crash_ipc_t * sentry__crash_ipc_init_app(HANDLE init_mutex) { - sentry_crash_ipc_t *ipc = SENTRY_MAKE(sentry_crash_ipc_t); + sentry_crash_ipc_t *ipc = SENTRY_MAKE_0(sentry_crash_ipc_t); if (!ipc) { return NULL; } - memset(ipc, 0, sizeof(sentry_crash_ipc_t)); ipc->is_daemon = false; ipc->init_mutex = init_mutex; // Use provided mutex (managed by backend) @@ -734,11 +729,10 @@ sentry__crash_ipc_init_daemon(pid_t app_pid, uint64_t app_tid, (void)event_handle; (void)ready_event_handle; - sentry_crash_ipc_t *ipc = SENTRY_MAKE(sentry_crash_ipc_t); + sentry_crash_ipc_t *ipc = SENTRY_MAKE_0(sentry_crash_ipc_t); if (!ipc) { return NULL; } - memset(ipc, 0, sizeof(sentry_crash_ipc_t)); ipc->is_daemon = true; // Open existing shared memory (using PID and thread ID) diff --git a/src/backends/sentry_backend_breakpad.cpp b/src/backends/sentry_backend_breakpad.cpp index e57f138204..31a8950419 100644 --- a/src/backends/sentry_backend_breakpad.cpp +++ b/src/backends/sentry_backend_breakpad.cpp @@ -331,11 +331,10 @@ sentry__backend_preload(void) sentry_backend_t * sentry__backend_new(void) { - auto *backend = SENTRY_MAKE(sentry_backend_t); + auto *backend = SENTRY_MAKE_0(sentry_backend_t); if (!backend) { return nullptr; } - memset(backend, 0, sizeof(sentry_backend_t)); backend->startup_func = breakpad_backend_startup; backend->shutdown_func = breakpad_backend_shutdown; diff --git a/src/backends/sentry_backend_crashpad.cpp b/src/backends/sentry_backend_crashpad.cpp index f0fda4bef7..b71d76f06e 100644 --- a/src/backends/sentry_backend_crashpad.cpp +++ b/src/backends/sentry_backend_crashpad.cpp @@ -1037,11 +1037,10 @@ sentry__backend_preload(void) sentry_backend_t * sentry__backend_new(void) { - auto *backend = SENTRY_MAKE(sentry_backend_t); + auto *backend = SENTRY_MAKE_0(sentry_backend_t); if (!backend) { return nullptr; } - memset(backend, 0, sizeof(sentry_backend_t)); auto *data = new (std::nothrow) crashpad_state_t {}; if (!data) { diff --git a/src/backends/sentry_backend_inproc.c b/src/backends/sentry_backend_inproc.c index 9da1fce26f..ad6c5c1a25 100644 --- a/src/backends/sentry_backend_inproc.c +++ b/src/backends/sentry_backend_inproc.c @@ -1810,11 +1810,10 @@ sentry__backend_preload(void) sentry_backend_t * sentry__backend_new(void) { - sentry_backend_t *backend = SENTRY_MAKE(sentry_backend_t); + sentry_backend_t *backend = SENTRY_MAKE_0(sentry_backend_t); if (!backend) { return NULL; } - memset(backend, 0, sizeof(sentry_backend_t)); backend->startup_func = startup_inproc_backend; backend->shutdown_func = shutdown_inproc_backend; diff --git a/src/backends/sentry_backend_native.c b/src/backends/sentry_backend_native.c index 32328fe499..95a2dce79a 100644 --- a/src/backends/sentry_backend_native.c +++ b/src/backends/sentry_backend_native.c @@ -117,11 +117,10 @@ native_backend_startup( sentry__mutex_unlock(&g_ipc_init_mutex); #endif - native_backend_state_t *state = SENTRY_MAKE(native_backend_state_t); + native_backend_state_t *state = SENTRY_MAKE_0(native_backend_state_t); if (!state) { return 1; } - memset(state, 0, sizeof(native_backend_state_t)); backend->data = state; // Initialize IPC (protected by global synchronization for concurrent @@ -930,13 +929,11 @@ sentry__backend_preload(void) sentry_backend_t * sentry__backend_new(void) { - sentry_backend_t *backend = SENTRY_MAKE(sentry_backend_t); + sentry_backend_t *backend = SENTRY_MAKE_0(sentry_backend_t); if (!backend) { return NULL; } - memset(backend, 0, sizeof(sentry_backend_t)); - backend->startup_func = native_backend_startup; backend->shutdown_func = native_backend_shutdown; backend->free_func = native_backend_free; diff --git a/src/sentry_alloc.c b/src/sentry_alloc.c index f0642ac445..eb84c0a034 100644 --- a/src/sentry_alloc.c +++ b/src/sentry_alloc.c @@ -21,6 +21,23 @@ sentry_malloc(size_t size) return malloc(size); } +void * +sentry__calloc(size_t count, size_t size) +{ + if (count && size > SIZE_MAX / count) { + return NULL; + } +#ifdef WITH_PAGE_ALLOCATOR + if (sentry__page_allocator_enabled()) { + // the page allocator is a bump allocator backed by mmap(MAP_ANONYMOUS), + // which the OS guarantees to be zeroed on first use, and the page + // allocator never reuses freed allocations + return sentry__page_allocator_alloc(count * size); + } +#endif + return calloc(count, size); +} + void sentry_free(void *ptr) { diff --git a/src/sentry_alloc.h b/src/sentry_alloc.h index fe7851369b..61231d4e33 100644 --- a/src/sentry_alloc.h +++ b/src/sentry_alloc.h @@ -8,4 +8,10 @@ */ #define SENTRY_MAKE(Type) (Type *)sentry_malloc(sizeof(Type)) +/** + * This is a typed `calloc` that zero-initializes the allocation. + */ +void *sentry__calloc(size_t count, size_t size); +#define SENTRY_MAKE_0(Type) (Type *)sentry__calloc(1, sizeof(Type)) + #endif diff --git a/src/sentry_attachment.c b/src/sentry_attachment.c index 4873d0a8dc..eb601f3af1 100644 --- a/src/sentry_attachment.c +++ b/src/sentry_attachment.c @@ -74,12 +74,11 @@ sentry__attachment_from_path(sentry_path_t *path) if (!path) { return NULL; } - sentry_attachment_t *attachment = SENTRY_MAKE(sentry_attachment_t); + sentry_attachment_t *attachment = SENTRY_MAKE_0(sentry_attachment_t); if (!attachment) { sentry__path_free(path); return NULL; } - memset(attachment, 0, sizeof(sentry_attachment_t)); attachment->path = path; return attachment; } @@ -95,12 +94,11 @@ sentry__attachment_from_buffer( sentry__path_free(filename); return NULL; } - sentry_attachment_t *attachment = SENTRY_MAKE(sentry_attachment_t); + sentry_attachment_t *attachment = SENTRY_MAKE_0(sentry_attachment_t); if (!attachment) { sentry__path_free(filename); return NULL; } - memset(attachment, 0, sizeof(sentry_attachment_t)); attachment->filename = filename; attachment->buf = sentry_malloc(buf_len * sizeof(char)); memcpy(attachment->buf, buf, buf_len * sizeof(char)); @@ -216,11 +214,10 @@ attachment_clone(const sentry_attachment_t *attachment) return NULL; } - sentry_attachment_t *clone = SENTRY_MAKE(sentry_attachment_t); + sentry_attachment_t *clone = SENTRY_MAKE_0(sentry_attachment_t); if (!clone) { return NULL; } - memset(clone, 0, sizeof(sentry_attachment_t)); if (attachment->path) { clone->path = sentry__path_clone(attachment->path); diff --git a/src/sentry_batcher.c b/src/sentry_batcher.c index a459239e0c..a8d605cd0a 100644 --- a/src/sentry_batcher.c +++ b/src/sentry_batcher.c @@ -3,7 +3,6 @@ #include "sentry_cpu_relax.h" #include "sentry_options.h" #include "sentry_utils.h" -#include // The batcher thread sleeps for this interval between flush cycles. // When the timer fires and there are items in the buffer, they are flushed @@ -24,11 +23,10 @@ sentry_batcher_t * sentry__batcher_new( sentry_batch_func_t batch_func, sentry_data_category_t data_category) { - sentry_batcher_t *batcher = SENTRY_MAKE(sentry_batcher_t); + sentry_batcher_t *batcher = SENTRY_MAKE_0(sentry_batcher_t); if (!batcher) { return NULL; } - memset(batcher, 0, sizeof(sentry_batcher_t)); batcher->refcount = 1; batcher->batch_func = batch_func; batcher->data_category = data_category; diff --git a/src/sentry_hint.c b/src/sentry_hint.c index c9588c9ca7..20561f18cb 100644 --- a/src/sentry_hint.c +++ b/src/sentry_hint.c @@ -10,11 +10,10 @@ sentry_hint_t * sentry_hint_new(void) { - sentry_hint_t *hint = SENTRY_MAKE(sentry_hint_t); + sentry_hint_t *hint = SENTRY_MAKE_0(sentry_hint_t); if (!hint) { return NULL; } - memset(hint, 0, sizeof(sentry_hint_t)); return hint; } diff --git a/src/sentry_options.c b/src/sentry_options.c index cdb4974848..98756a6455 100644 --- a/src/sentry_options.c +++ b/src/sentry_options.c @@ -14,11 +14,10 @@ sentry_options_t * sentry_options_new(void) { - sentry_options_t *opts = SENTRY_MAKE(sentry_options_t); + sentry_options_t *opts = SENTRY_MAKE_0(sentry_options_t); if (!opts) { return NULL; } - memset(opts, 0, sizeof(sentry_options_t)); opts->database_path = sentry__path_from_str(".sentry-native"); // we assume the DSN to be ASCII only sentry_options_set_dsn(opts, getenv("SENTRY_DSN")); diff --git a/src/sentry_retry.c b/src/sentry_retry.c index 0c22e880e0..9904806f74 100644 --- a/src/sentry_retry.c +++ b/src/sentry_retry.c @@ -40,11 +40,10 @@ struct sentry_retry_s { sentry_retry_t * sentry__retry_new(const sentry_options_t *options) { - sentry_retry_t *retry = SENTRY_MAKE(sentry_retry_t); + sentry_retry_t *retry = SENTRY_MAKE_0(sentry_retry_t); if (!retry) { return NULL; } - memset(retry, 0, sizeof(sentry_retry_t)); sentry__mutex_init(&retry->sealed_lock); retry->run = sentry__run_incref(options->run); retry->cache_keep = options->cache_keep; diff --git a/src/sentry_scope.c b/src/sentry_scope.c index adede82984..d4d0f0f946 100644 --- a/src/sentry_scope.c +++ b/src/sentry_scope.c @@ -68,7 +68,6 @@ get_client_sdk(void) static void init_scope(sentry_scope_t *scope) { - memset(scope, 0, sizeof(sentry_scope_t)); scope->release = NULL; scope->environment = NULL; scope->transaction = NULL; @@ -96,6 +95,7 @@ get_scope(void) return &g_scope; } + memset(&g_scope, 0, sizeof(sentry_scope_t)); init_scope(&g_scope); sentry_value_set_by_key(g_scope.contexts, "os", sentry__get_os_context()); g_scope.client_sdk = get_client_sdk(); @@ -169,7 +169,7 @@ sentry__scope_flush_unlock(void) sentry_scope_t * sentry_local_scope_new(void) { - sentry_scope_t *scope = SENTRY_MAKE(sentry_scope_t); + sentry_scope_t *scope = SENTRY_MAKE_0(sentry_scope_t); if (!scope) { return NULL; } diff --git a/src/sentry_sync.c b/src/sentry_sync.c index 38d3826be3..daaa48e2b2 100644 --- a/src/sentry_sync.c +++ b/src/sentry_sync.c @@ -176,14 +176,13 @@ struct sentry_bgworker_s { sentry_bgworker_t * sentry__bgworker_new(void *state, void (*free_state)(void *state)) { - sentry_bgworker_t *bgw = SENTRY_MAKE(sentry_bgworker_t); + sentry_bgworker_t *bgw = SENTRY_MAKE_0(sentry_bgworker_t); if (!bgw) { if (free_state) { free_state(state); } return NULL; } - memset(bgw, 0, sizeof(sentry_bgworker_t)); sentry__thread_init(&bgw->thread_id); sentry__mutex_init(&bgw->task_lock); sentry__cond_init(&bgw->submit_signal); @@ -369,12 +368,10 @@ sentry__bgworker_flush(sentry_bgworker_t *bgw, uint64_t timeout) } SENTRY_DEBUG("flushing background worker thread"); - sentry_flush_task_t *flush_task - = sentry_malloc(sizeof(sentry_flush_task_t)); + sentry_flush_task_t *flush_task = SENTRY_MAKE_0(sentry_flush_task_t); if (!flush_task) { return 1; } - memset(flush_task, 0, sizeof(sentry_flush_task_t)); flush_task->refcount = 2; // this thread + background worker flush_task->was_flushed = false; sentry__cond_init(&flush_task->signal); diff --git a/src/sentry_transport.c b/src/sentry_transport.c index cc9542293f..04d748d176 100644 --- a/src/sentry_transport.c +++ b/src/sentry_transport.c @@ -20,11 +20,10 @@ sentry_transport_t * sentry_transport_new( void (*send_func)(sentry_envelope_t *envelope, void *state)) { - sentry_transport_t *transport = SENTRY_MAKE(sentry_transport_t); + sentry_transport_t *transport = SENTRY_MAKE_0(sentry_transport_t); if (!transport) { return NULL; } - memset(transport, 0, sizeof(sentry_transport_t)); transport->send_envelope_func = send_func; return transport; diff --git a/src/sentry_utils.c b/src/sentry_utils.c index 6de8d80d39..34e83ea295 100644 --- a/src/sentry_utils.c +++ b/src/sentry_utils.c @@ -234,11 +234,10 @@ sentry__dsn_new_n(const char *raw_dsn, size_t raw_dsn_len) // org_id is u64 in relay, so needs 20 characters + null termination char org_id[21] = ""; - sentry_dsn_t *dsn = SENTRY_MAKE(sentry_dsn_t); + sentry_dsn_t *dsn = SENTRY_MAKE_0(sentry_dsn_t); if (!dsn) { return NULL; } - memset(dsn, 0, sizeof(sentry_dsn_t)); dsn->refcount = 1; dsn->raw = sentry__string_clone_n(raw_dsn, raw_dsn_len); diff --git a/src/sentry_value.c b/src/sentry_value.c index 9d6e9e654a..48409112bd 100644 --- a/src/sentry_value.c +++ b/src/sentry_value.c @@ -390,9 +390,8 @@ sentry_value_new_string(const char *value) sentry_value_t sentry_value_new_list(void) { - list_t *l = SENTRY_MAKE(list_t); + list_t *l = SENTRY_MAKE_0(list_t); if (l) { - memset(l, 0, sizeof(list_t)); sentry_value_t rv = new_thing_value(l, THING_TYPE_LIST); if (sentry_value_is_null(rv)) { sentry_free(l); @@ -406,9 +405,8 @@ sentry_value_new_list(void) sentry_value_t sentry__value_new_list_with_size(size_t size) { - list_t *l = SENTRY_MAKE(list_t); + list_t *l = SENTRY_MAKE_0(list_t); if (l) { - memset(l, 0, sizeof(list_t)); l->allocated = size; if (size) { l->items = sentry_malloc(sizeof(sentry_value_t) * size); @@ -431,9 +429,8 @@ sentry__value_new_list_with_size(size_t size) sentry_value_t sentry_value_new_object(void) { - obj_t *o = SENTRY_MAKE(obj_t); + obj_t *o = SENTRY_MAKE_0(obj_t); if (o) { - memset(o, 0, sizeof(obj_t)); sentry_value_t rv = new_thing_value(o, THING_TYPE_OBJECT); if (sentry_value_is_null(rv)) { sentry_free(o); @@ -447,9 +444,8 @@ sentry_value_new_object(void) sentry_value_t sentry__value_new_object_with_size(size_t size) { - obj_t *o = SENTRY_MAKE(obj_t); + obj_t *o = SENTRY_MAKE_0(obj_t); if (o) { - memset(o, 0, sizeof(obj_t)); o->allocated = size; if (size) { o->pairs = sentry_malloc(sizeof(obj_pair_t) * size); diff --git a/src/transports/sentry_http_transport.c b/src/transports/sentry_http_transport.c index e64512da32..978ee93bde 100644 --- a/src/transports/sentry_http_transport.c +++ b/src/transports/sentry_http_transport.c @@ -470,11 +470,10 @@ http_transport_submit_cleanup( sentry_transport_t * sentry__http_transport_new(void *client, sentry_http_send_func_t send_func) { - http_transport_state_t *state = SENTRY_MAKE(http_transport_state_t); + http_transport_state_t *state = SENTRY_MAKE_0(http_transport_state_t); if (!state) { return NULL; } - memset(state, 0, sizeof(http_transport_state_t)); state->ratelimiter = sentry__rate_limiter_new(); state->client = client; state->send_func = send_func; diff --git a/src/transports/sentry_http_transport_curl.c b/src/transports/sentry_http_transport_curl.c index 1954c8e5bf..8aabd17a3f 100644 --- a/src/transports/sentry_http_transport_curl.c +++ b/src/transports/sentry_http_transport_curl.c @@ -30,11 +30,10 @@ typedef struct { static curl_client_t * curl_client_new(void) { - curl_client_t *client = SENTRY_MAKE(curl_client_t); + curl_client_t *client = SENTRY_MAKE_0(curl_client_t); if (!client) { return NULL; } - memset(client, 0, sizeof(curl_client_t)); #ifdef SENTRY_PLATFORM_NX client->nx_state = sentry_nx_curl_state_new(); diff --git a/src/transports/sentry_http_transport_winhttp.c b/src/transports/sentry_http_transport_winhttp.c index 8f918937ef..0b06c79e4c 100644 --- a/src/transports/sentry_http_transport_winhttp.c +++ b/src/transports/sentry_http_transport_winhttp.c @@ -28,11 +28,10 @@ typedef struct { static winhttp_client_t * winhttp_client_new(void) { - winhttp_client_t *client = SENTRY_MAKE(winhttp_client_t); + winhttp_client_t *client = SENTRY_MAKE_0(winhttp_client_t); if (!client) { return NULL; } - memset(client, 0, sizeof(winhttp_client_t)); return client; }