[PATCH v3 6/7] trace2: remove use of ALLOC_GROW()
- From
Derrick Stolee via GitGitGadget <gitgitgadget@gmail.com>
- Date
- Aug 31, 2026, 17:25 UTC
- Message-ID
- <ccd284fbebcdc43812948bbd8b2d413dbf2b260d.1788197143.git.gitgitgadget@gmail.com>
- In-Reply-To
- <pull.2178.v3.git.1788197143.gitgitgadget@gmail.com>
From: Derrick Stolee <stolee@gmail.com>
The ALLOC_GROW() helper can call die() on a failed memory allocation. We need to remove this from the trace2 API code to prevent a recursive die() handler.
This helper is used to track the nested region stack. Use a new skipped_regions member to track how many times a region was entered without being added to the stack, and decrease that amount as we leave each region. This allows us to avoid a failure and instead stop deepening the stack, giving as much nesting behavior as possible without failing the entire process.
Helped-by: Elijah Newren <newren@gmail.com> Signed-off-by: Derrick Stolee <stolee@gmail.com> --- banned-die.h | 3 +++ trace2/tr2_tls.c | 34 +++++++++++++++++++++++++++++++++- trace2/tr2_tls.h | 1 + 3 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/banned-die.h b/banned-die.h index 4d1800353d..cff1072397 100644 --- a/banned-die.h +++ b/banned-die.h @@ -23,4 +23,7 @@ #undef ALLOC_ARRAY #define ALLOC_ARRAY(x, alloc) BANNED(ALLOC_ARRAY) +#undef ALLOC_GROW +#define ALLOC_GROW(x, nr, alloc) BANNED(ALLOC_GROW) + #endif /* BANNED_DIE_H */ diff --git a/trace2/tr2_tls.c b/trace2/tr2_tls.c index 49bd505d62..5e4624d0b3 100644 --- a/trace2/tr2_tls.c +++ b/trace2/tr2_tls.c @@ -109,8 +109,33 @@ void tr2tls_unset_self(void) void tr2tls_push_self(uint64_t us_now) { struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); + uint64_t *new_array; + size_t new_alloc; + + if (ctx->nr_skipped_regions) { + ctx->nr_skipped_regions++; + return; + } + + if (ctx->nr_open_regions >= ctx->alloc) { + if (ctx->alloc > + SIZE_MAX / (2 * sizeof(*ctx->array_us_start))) { + ctx->nr_skipped_regions++; + return; + } + new_alloc = ctx->alloc * 2; + + new_array = realloc(ctx->array_us_start, + new_alloc * sizeof(*ctx->array_us_start)); + if (!new_array) { + ctx->nr_skipped_regions++; + return; + } + + ctx->array_us_start = new_array; + ctx->alloc = new_alloc; + } - ALLOC_GROW(ctx->array_us_start, ctx->nr_open_regions + 1, ctx->alloc); ctx->array_us_start[ctx->nr_open_regions++] = us_now; } @@ -118,6 +143,11 @@ void tr2tls_pop_self(void) { struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); + if (ctx->nr_skipped_regions) { + ctx->nr_skipped_regions--; + return; + } + if (!ctx->nr_open_regions) BUG("no open regions in thread '%s'", ctx->thread_name); @@ -138,6 +168,8 @@ uint64_t tr2tls_region_elasped_self(uint64_t us) uint64_t us_start; ctx = tr2tls_get_self(); + if (ctx->nr_skipped_regions) + return 0; if (!ctx->nr_open_regions) return 0; diff --git a/trace2/tr2_tls.h b/trace2/tr2_tls.h index 3bdbf4d275..c365017923 100644 --- a/trace2/tr2_tls.h +++ b/trace2/tr2_tls.h @@ -20,6 +20,7 @@ struct tr2tls_thread_ctx { uint64_t *array_us_start; size_t alloc; size_t nr_open_regions; /* plays role of "nr" in ALLOC_GROW */ + size_t nr_skipped_regions; int thread_id; struct tr2_timer_block timer_block; struct tr2_counter_block counter_block;
-- gitgitgadget