From 120af06c158c4027599dfcbe6d959f6a7a94c398 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Jan 21 2016 14:36:19 +0000 Subject: Add valgrind-3.11.0-x86_unwind.patch --- diff --git a/valgrind-3.11.0-x86_unwind.patch b/valgrind-3.11.0-x86_unwind.patch new file mode 100644 index 0000000..ca0063b --- /dev/null +++ b/valgrind-3.11.0-x86_unwind.patch @@ -0,0 +1,109 @@ +commit f250c4d3241c156f8e65398e2af76e3e2ee1ccb5 +Author: philippe +Date: Wed Nov 18 20:56:55 2015 +0000 + + Fix incorrect (or infinite loop) unwind on RHEL7 x86 32 bits. + + On RHEL7 x86 32 bits, Valgrind unwinder cannot properly unwind + the stack just after a thread creation : the unwinder always retrieves + the same pc/sp/bp. + See below for an example. + This has as consequences that some stack traces are bigger than + needed (i.e. they always fill up the ips array). If + --merge-recursive-frames is given, then the unwinder enters in an + infinite loop (as identical frames will be merged, and the ips array + will never be filled in). + Thi patch adds an additional exit condition : after unwinding + a frame, if the previous sp is >= new sp, then unwinding stops. + Patch has been tested on debian 8/x86, RHEL7/x86. + + + + 0x0417db67 <+55>: mov 0x18(%esp),%ebx + 0x0417db6b <+59>: mov 0x28(%esp),%edi + 0x0417db6f <+63>: mov $0x78,%eax + 0x0417db74 <+68>: mov %ebx,(%ecx) + 0x0417db76 <+70>: int $0x80 + => 0x0417db78 <+72>: pop %edi + 0x0417db79 <+73>: pop %esi + 0x0417db7a <+74>: pop %ebx + 0x0417db7b <+75>: test %eax,%eax + + Valgrind stacktrace gives: + ==21261== at 0x417DB78: clone (clone.S:110) + ==21261== by 0x424702F: ??? + ==21261== by 0x424702F: ??? + ==21261== by 0x424702F: ??? + ==21261== by 0x424702F: ??? + ==21261== by 0x424702F: ??? + ==21261== by 0x424702F: ??? + ==21261== by 0x424702F: ??? + ... + (till the array of ips is full) + + while gdb stacktrace gives: + (gdb) bt + #0 clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:110 + #1 0x00000000 in ?? () + (gdb) p $pc + $2 = (void (*)()) 0x417db78 + (gdb) + + + With the fix, valgrind gives: + ==21261== at 0x417DB78: clone (clone.S:110) + ==21261== by 0x424702F: ??? + which looks more reasonable. + + + + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15729 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/coregrind/m_stacktrace.c b/coregrind/m_stacktrace.c +index 8c1e9a4..137e780 100644 +--- a/coregrind/m_stacktrace.c ++++ b/coregrind/m_stacktrace.c +@@ -350,6 +350,8 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, + uregs.xbp <= fp_max - 1 * sizeof(UWord)/*see comment below*/ && + VG_IS_4_ALIGNED(uregs.xbp)) + { ++ Addr old_xsp; ++ + /* fp looks sane, so use it. */ + uregs.xip = (((UWord*)uregs.xbp)[1]); + // We stop if we hit a zero (the traditional end-of-stack +@@ -382,6 +384,7 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, + } + } + ++ old_xsp = uregs.xsp; + uregs.xsp = uregs.xbp + sizeof(Addr) /*saved %ebp*/ + + sizeof(Addr) /*ra*/; + uregs.xbp = (((UWord*)uregs.xbp)[0]); +@@ -393,6 +396,12 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, + if (debug) VG_(printf)(" cache FPUNWIND >2\n"); + if (debug) unwind_case = "FO"; + if (do_stats) stats.FO++; ++ if (old_xsp >= uregs.xsp) { ++ if (debug) ++ VG_(printf) (" FO end of stack old_xsp %p >= xsp %p\n", ++ (void*)old_xsp, (void*)uregs.xsp); ++ break; ++ } + } else { + fp_CF_verif_cache [hash] = xip_verified ^ CFUNWIND; + if (debug) VG_(printf)(" cache CFUNWIND >2\n"); +@@ -406,6 +415,12 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, + } else { + if (debug) unwind_case = "FF"; + if (do_stats) stats.FF++; ++ 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; ++ } + } + goto unwind_done; + } else { diff --git a/valgrind.spec b/valgrind.spec index 3f3e746..4e12125 100644 --- a/valgrind.spec +++ b/valgrind.spec @@ -95,6 +95,9 @@ Patch15: valgrind-3.11.0-socketcall-x86-linux.patch # KDE#356044 Dwarf line info reader misinterprets is_stmt register Patch16: valgrind-3.11.0-is_stmt.patch +# Fix incorrect (or infinite loop) unwind on RHEL7 x86 32 bits. (svn r15729) +Patch17: valgrind-3.11.0-x86_unwind.patch + %if %{build_multilib} # Ensure glibc{,-devel} is installed for both multilib arches BuildRequires: /lib/libc.so.6 /usr/lib/libc.so /lib64/libc.so.6 /usr/lib64/libc.so @@ -215,6 +218,7 @@ Valgrind User Manual for details. %patch14 -p1 %patch15 -p1 %patch16 -p1 +%patch17 -p1 %build # We need to use the software collection compiler and binutils if available. @@ -415,6 +419,7 @@ echo ===============END TESTING=============== - Don't strip debuginfo from vgpreload libaries. Enable dwz for everything else again. - Add valgrind-3.11.0-is_stmt.patch +- Add valgrind-3.11.0-x86_unwind.patch * Tue Jan 19 2016 Mark Wielaard - 3.11.0-7 - Add valgrind-3.11.0-pthread_barrier.patch