From: Julian Seward Date: Mon, 14 Feb 2011 11:10:53 +0000 (+0000) Subject: Merge from trunk, r11523 and r11524 (fixes for #246152, segfault on X-Git-Tag: svn/VALGRIND_3_6_1~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=494b8d7d0f5bd0589f371f9d863d96ff49cc846a;p=thirdparty%2Fvalgrind.git Merge from trunk, r11523 and r11524 (fixes for #246152, segfault on pthread_cancel) git-svn-id: svn://svn.valgrind.org/valgrind/branches/VALGRIND_3_6_BRANCH@11554 --- diff --git a/callgrind/bbcc.c b/callgrind/bbcc.c index 24862a80ca..bab4858544 100644 --- a/callgrind/bbcc.c +++ b/callgrind/bbcc.c @@ -741,7 +741,11 @@ void CLG_(setup_bbcc)(BB* bb) } } else { - CLG_(unwind_call_stack)(sp, 0); + Int unwind_count = CLG_(unwind_call_stack)(sp, 0); + if (unwind_count > 0) { + /* if unwinding was done, this actually is a return */ + jmpkind = Ijk_Ret; + } if (jmpkind == Ijk_Call) { delayed_push = True; diff --git a/callgrind/callstack.c b/callgrind/callstack.c index 24087f5bc3..ec48369c73 100644 --- a/callgrind/callstack.c +++ b/callgrind/callstack.c @@ -394,11 +394,13 @@ void CLG_(pop_call_stack)() } -/* remove CallStack items to sync with current SP +/* Unwind enough CallStack items to sync with current stack pointer. + * Returns the number of stack frames unwinded. */ -void CLG_(unwind_call_stack)(Addr sp, Int minpops) +Int CLG_(unwind_call_stack)(Addr sp, Int minpops) { Int csp; + Int unwind_count = 0; CLG_DEBUG(4,"+ unwind_call_stack(sp %#lx, minpops %d): frame %d\n", sp, minpops, CLG_(current_call_stack).sp); @@ -415,6 +417,7 @@ void CLG_(unwind_call_stack)(Addr sp, Int minpops) ((top_ce->sp == sp) && minpops>0)) { minpops--; + unwind_count++; CLG_(pop_call_stack)(); csp=CLG_(current_call_stack).sp; continue; @@ -423,4 +426,5 @@ void CLG_(unwind_call_stack)(Addr sp, Int minpops) } CLG_DEBUG(4,"- unwind_call_stack\n"); + return unwind_count; } diff --git a/callgrind/global.h b/callgrind/global.h index bfb5a48168..d66e631e31 100644 --- a/callgrind/global.h +++ b/callgrind/global.h @@ -779,7 +779,7 @@ call_entry* CLG_(get_call_entry)(Int n); void CLG_(push_call_stack)(BBCC* from, UInt jmp, BBCC* to, Addr sp, Bool skip); void CLG_(pop_call_stack)(void); -void CLG_(unwind_call_stack)(Addr sp, Int); +Int CLG_(unwind_call_stack)(Addr sp, Int); /* from context.c */ void CLG_(init_fn_stack)(fn_stack*); diff --git a/callgrind/jumps.c b/callgrind/jumps.c index fc306af0d5..50b35af2a4 100644 --- a/callgrind/jumps.c +++ b/callgrind/jumps.c @@ -160,6 +160,8 @@ static jCC* new_jcc(BBCC* from, UInt jmp, BBCC* to) * This list is only used at dumping time */ if (from) { + /* Prohibit corruption by array overrun */ + CLG_ASSERT((0 <= jmp) && (jmp <= from->bb->cjmp_count)); jcc->next_from = from->jmp[jmp].jcc_list; from->jmp[jmp].jcc_list = jcc; }