]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix incorrect (or infinite loop) unwind on RHEL7 amd64 64 bits.
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Wed, 17 Feb 2016 22:41:14 +0000 (22:41 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Wed, 17 Feb 2016 22:41:14 +0000 (22:41 +0000)
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

NEWS
coregrind/m_stacktrace.c

diff --git a/NEWS b/NEWS
index ba4828f3ad7a1a091140fe5f648eb3debf949276..e749dd84f39cb7262ade8b08768d16a88f151383 100644 (file)
--- 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.
 
index 137e780d014761bbe1577a8d43215b86871a8175..ef4984c3a2689517d830672e6dc6c4a000c9ba65 100644 (file)
@@ -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;