From 21dfa7e88f17465c289fa44049a3c6abf9731672 Mon Sep 17 00:00:00 2001 From: "beard%netscape.com" Date: Tue, 27 Feb 2001 01:09:44 +0000 Subject: [PATCH] [not part of build] "fixes" the stack during GC initialization, so later stack crawls won't crash. --- gc/boehm/os_dep.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/gc/boehm/os_dep.c b/gc/boehm/os_dep.c index 61cc157bb41..69e760079fe 100644 --- a/gc/boehm/os_dep.c +++ b/gc/boehm/os_dep.c @@ -2343,7 +2343,8 @@ static call_tree* find_tree(stack_frame* frame) /* primordial root of the call tree. */ static call_tree root = { 0, 0, 0, 0, 0 }; - if ((frame == NULL) || ((word)frame & 0x1)) + /* ensure frame is non-NULL and 4-byte aligned. */ + if ((frame == NULL) || ((word)frame & 0x3)) return &root; else { call_tree* parent = find_tree(frame->next); @@ -2381,18 +2382,41 @@ static call_tree* find_tree(stack_frame* frame) } } +static int fix_stack(stack_frame* frame) +{ + // only fix the REAL stack. + if (! GC_base(frame)) { + Ptr stackBase = LMGetCurStackBase(); + while (frame) { + // if we find a bogus frame in the stack, we clear it out. + if (frame->next < frame || (Ptr)frame->next > stackBase) { + frame->next = NULL; + return 1; + } + frame = frame->next; + } + } + return 0; +} + void GC_save_callers(struct callinfo info[NFRAMES]) { int i; stack_frame* currentFrame; - call_tree* currentTree; + call_tree* currentTree = NULL; currentFrame = getStackFrame(); // GC_save_callers's frame. currentFrame = currentFrame->next; // GC_debug_malloc's frame. currentFrame = currentFrame->next; // GC_debug_malloc's caller's frame. - - currentTree = find_tree(currentFrame); - + + if (info != GC_last_stack) { + currentTree = find_tree(currentFrame); + } else { + static int fixed_stack = 0; + if (!fixed_stack) + fixed_stack = fix_stack(currentFrame); + } + info[0].ci_pc = (word) currentTree; info[1].ci_pc = 0; }