From: Philippe Waroquiers Date: Wed, 17 Feb 2016 22:41:14 +0000 (+0000) Subject: Fix incorrect (or infinite loop) unwind on RHEL7 amd64 64 bits. X-Git-Tag: svn/VALGRIND_3_12_0~229 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=be2da24d6c23e6376ba6e7435049eb54a0d8e935;p=thirdparty%2Fvalgrind.git Fix incorrect (or infinite loop) unwind on RHEL7 amd64 64 bits. Same kind of problems as explained and fixed in revision 15720: In some cases, unwinding always retrieves the same pc/sp/bp. Fix for 64 bits is similar: stop unwinding if the previous sp is >= new sp git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15794 --- diff --git a/NEWS b/NEWS index ba4828f3ad..e749dd84f3 100644 --- a/NEWS +++ b/NEWS @@ -70,11 +70,11 @@ where XXXXXX is the bug number as listed below. 357871 pthread_spin_destroy not properly wrapped 357887 Fix a file handle leak. VG_(fclose) did not close the file 358030 support direct socket calls on x86 32bit (new in linux 4.3) -359201 futex syscall "skips" argument 5 if op is FUTEX_WAIT_BITSET 359133 Assertion 'eltSzB <= ddpa->poolSzB' failed +359201 futex syscall "skips" argument 5 if op is FUTEX_WAIT_BITSET 359289 s390x: popcnt (B9E1) not implemented -n-i-bz Fix incorrect (or infinite loop) unwind on RHEL7 x86 32 bits +n-i-bz Fix incorrect (or infinite loop) unwind on RHEL7 x86 and amd64 n-i-bz massif --pages-as-heap=yes does not report peak caused by mmap+munmap n-i-bz false positive leaks due to aspacemgr merging non heap segments with heap segments. diff --git a/coregrind/m_stacktrace.c b/coregrind/m_stacktrace.c index 137e780d01..ef4984c3a2 100644 --- a/coregrind/m_stacktrace.c +++ b/coregrind/m_stacktrace.c @@ -607,16 +607,25 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, * next function which is completely wrong. */ while (True) { + Addr old_xsp; if (i >= max_n_ips) break; + old_xsp = uregs.xsp; + /* Try to derive a new (ip,sp,fp) triple from the current set. */ /* First off, see if there is any CFI info to hand which can be used. */ if ( VG_(use_CF_info)( &uregs, fp_min, fp_max ) ) { if (0 == uregs.xip || 1 == uregs.xip) break; + if (old_xsp >= uregs.xsp) { + if (debug) + VG_(printf) (" CF end of stack old_xsp %p >= xsp %p\n", + (void*)old_xsp, (void*)uregs.xsp); + break; + } if (sps) sps[i] = uregs.xsp; if (fps) fps[i] = uregs.xbp; ips[i++] = uregs.xip - 1; /* -1: refer to calling insn, not the RA */ @@ -646,6 +655,12 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, if (0 == uregs.xip || 1 == uregs.xip) break; uregs.xsp = uregs.xbp + sizeof(Addr) /*saved %rbp*/ + sizeof(Addr) /*ra*/; + if (old_xsp >= uregs.xsp) { + if (debug) + VG_(printf) (" FF end of stack old_xsp %p >= xsp %p\n", + (void*)old_xsp, (void*)uregs.xsp); + break; + } uregs.xbp = (((UWord*)uregs.xbp)[0]); if (sps) sps[i] = uregs.xsp; if (fps) fps[i] = uregs.xbp;