trace2: remove use of ALLOC_GROW()

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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
seen
Derrick Stolee 2026-08-31 17:25:42 +00:00 committed by Junio C Hamano
parent 8c7b68a8bf
commit 4adf78e107
3 changed files with 37 additions and 1 deletions

View File

@ -23,4 +23,7 @@
#undef ALLOC_ARRAY #undef ALLOC_ARRAY
#define ALLOC_ARRAY(x, alloc) BANNED(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 */ #endif /* BANNED_DIE_H */

View File

@ -109,8 +109,33 @@ void tr2tls_unset_self(void)
void tr2tls_push_self(uint64_t us_now) void tr2tls_push_self(uint64_t us_now)
{ {
struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); 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; 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(); struct tr2tls_thread_ctx *ctx = tr2tls_get_self();


if (ctx->nr_skipped_regions) {
ctx->nr_skipped_regions--;
return;
}

if (!ctx->nr_open_regions) if (!ctx->nr_open_regions)
BUG("no open regions in thread '%s'", ctx->thread_name); 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; uint64_t us_start;


ctx = tr2tls_get_self(); ctx = tr2tls_get_self();
if (ctx->nr_skipped_regions)
return 0;
if (!ctx->nr_open_regions) if (!ctx->nr_open_regions)
return 0; return 0;



View File

@ -20,6 +20,7 @@ struct tr2tls_thread_ctx {
uint64_t *array_us_start; uint64_t *array_us_start;
size_t alloc; size_t alloc;
size_t nr_open_regions; /* plays role of "nr" in ALLOC_GROW */ size_t nr_open_regions; /* plays role of "nr" in ALLOC_GROW */
size_t nr_skipped_regions;
int thread_id; int thread_id;
struct tr2_timer_block timer_block; struct tr2_timer_block timer_block;
struct tr2_counter_block counter_block; struct tr2_counter_block counter_block;