From a86f3c04a52515cfd830ae740cc264b98be90e7a Mon Sep 17 00:00:00 2001 From: Philipp Hahn Date: Mon, 24 Mar 2025 14:02:03 +0100 Subject: [PATCH] trace: fix SIGSEGV after pop Calling `trace_pop_target()` invalidates the linked list of `target_stack_node_t`s by `free()`ing the node and its `p_target`. But `p_stack_top` may still points at that now freed node. Entering the debugger will crash as it will start from `p_stack_top`. 1. Explicitly invalidate `p_target` by setting it to `NULL`. 2. Explicitly pop the top node from `p_stack_top` before calling `trace_pop_target()`. Closes: #158 Signed-off-by: Philipp Hahn --- src/remake.c | 8 ++++++++ src/trace.c | 1 + 2 files changed, 9 insertions(+) diff --git a/src/remake.c b/src/remake.c index e5f6d0443..84cde9e20 100644 --- a/src/remake.c +++ b/src/remake.c @@ -456,6 +456,7 @@ update_file_1 (struct file *file, unsigned int depth, } DBF (DB_VERBOSE, _("File '%s' was considered already.\n")); + p_stack_top = p_stack_top->p_parent; trace_pop_target(p_call_stack); return 0; } @@ -467,10 +468,12 @@ update_file_1 (struct file *file, unsigned int depth, break; case cs_running: DBF (DB_VERBOSE, _("Still updating file '%s'.\n")); + p_stack_top = p_stack_top->p_parent; trace_pop_target(p_call_stack); return 0; case cs_finished: DBF (DB_VERBOSE, _("Finished updating file '%s'.\n")); + p_stack_top = p_stack_top->p_parent; trace_pop_target(p_call_stack); return file->update_status; default: @@ -707,6 +710,7 @@ update_file_1 (struct file *file, unsigned int depth, set_command_state (file, cs_deps_running); --depth; DBF (DB_VERBOSE, _("The prerequisites of '%s' are being made.\n")); + p_stack_top = p_stack_top->p_parent; trace_pop_target(p_call_stack); return 0; } @@ -728,6 +732,7 @@ update_file_1 (struct file *file, unsigned int depth, OS (error, NILF, _("Target '%s' not remade because of errors."), file->name); + p_stack_top = p_stack_top->p_parent; trace_pop_target(p_call_stack); return dep_status; } @@ -838,6 +843,7 @@ update_file_1 (struct file *file, unsigned int depth, } notice_finished_file (file); + p_stack_top = p_stack_top->p_parent; trace_pop_target(p_call_stack); /* Since we don't need to remake the file, convert it to use the @@ -871,6 +877,7 @@ update_file_1 (struct file *file, unsigned int depth, DBF (DB_VERBOSE, _("Recipe of '%s' is being run.\n")); if ( file->tracing & BRK_AFTER_CMD || i_debugger_stepping ) enter_debugger(p_call_stack, file, 0, DEBUG_BRKPT_AFTER_CMD); + p_stack_top = p_stack_top->p_parent; trace_pop_target(p_call_stack); return 0; } @@ -894,6 +901,7 @@ update_file_1 (struct file *file, unsigned int depth, if ( file->tracing & BRK_AFTER_CMD || i_debugger_stepping ) enter_debugger(p_call_stack, file, 0, DEBUG_BRKPT_AFTER_CMD); + p_stack_top = p_stack_top->p_parent; trace_pop_target(p_call_stack); return file->update_status; } diff --git a/src/trace.c b/src/trace.c index 53b4622aa..921425080 100644 --- a/src/trace.c +++ b/src/trace.c @@ -91,6 +91,7 @@ trace_pop_target (target_stack_node_t *p) } free(p->p_target); + p->p_target = NULL; free(p); }