|
From: <sv...@va...> - 2006-04-29 18:03:20
|
Author: sewardj
Date: 2006-04-29 19:03:14 +0100 (Sat, 29 Apr 2006)
New Revision: 5868
Log:
Get rid of VG_(x86_linux_REDIR_FOR__dl_sysinfo_int80) and do the x86-linu=
x
stack unwind kludge another way. This is believed to fix #108258.
Modified:
trunk/coregrind/m_clientstate.c
trunk/coregrind/m_redir.c
trunk/coregrind/m_signals.c
trunk/coregrind/m_stacktrace.c
trunk/coregrind/m_trampoline.S
trunk/coregrind/pub_core_clientstate.h
trunk/coregrind/pub_core_trampoline.h
Modified: trunk/coregrind/m_clientstate.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_clientstate.c 2006-04-29 18:01:46 UTC (rev 5867)
+++ trunk/coregrind/m_clientstate.c 2006-04-29 18:03:14 UTC (rev 5868)
@@ -91,7 +91,13 @@
/* Where is the __libc_freeres_wrapper routine we made? */
Addr VG_(client___libc_freeres_wrapper) =3D 0;
=20
+/* x86-linux only: where is glibc's _dl_sysinfo_int80 function?
+ Finding it isn't essential, but knowing where it is does sometimes
+ help produce better back traces. See big comment in
+ VG_(get_StackTrace) in m_stacktrace.c for further info. */
+Addr VG_(client__dl_sysinfo_int80) =3D 0;
=20
+
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
Modified: trunk/coregrind/m_redir.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_redir.c 2006-04-29 18:01:46 UTC (rev 5867)
+++ trunk/coregrind/m_redir.c 2006-04-29 18:03:14 UTC (rev 5868)
@@ -273,7 +273,8 @@
static void show_redir_state ( HChar* who );
static void show_active ( HChar* left, Active* act );
=20
-static void handle_maybe_load_notifier( HChar* symbol, Addr addr );
+static void handle_maybe_load_notifier( const UChar* soname,=20
+ HChar* symbol, Addr addr=
);
=20
=20
/*------------------------------------------------------------*/
@@ -310,8 +311,11 @@
HChar demangled_sopatt[N_DEMANGLED];
HChar demangled_fnpatt[N_DEMANGLED];
=20
+ const UChar* newsi_soname;
+
vg_assert(newsi);
- vg_assert(VG_(seginfo_soname)(newsi) !=3D NULL);
+ newsi_soname =3D VG_(seginfo_soname)(newsi);
+ vg_assert(newsi_soname !=3D NULL);
=20
/* stay sane: we don't already have this. */
for (ts =3D topSpecs; ts; ts =3D ts->next)
@@ -330,7 +334,7 @@
if (!ok) {
/* It's not a full-scale redirect, but perhaps it is a load-not=
ify
fn? Let the load-notify department see it. */
- handle_maybe_load_notifier( sym_name, sym_addr );
+ handle_maybe_load_notifier( newsi_soname, sym_name, sym_addr );
continue;=20
}
spec =3D symtab_alloc(sizeof(Spec));
@@ -726,13 +730,6 @@
// The rest of this function just adds initial Specs. =20
=20
# if defined(VGP_x86_linux)
- /* Redirect _dl_sysinfo_int80, which is glibc's default system call
- routine, to our copy so that the special sysinfo unwind hack in
- m_stacktrace.c will kick in. */
- add_hardwired_spec(
- "ld-linux.so.2", "_dl_sysinfo_int80",
- (Addr)&VG_(x86_linux_REDIR_FOR__dl_sysinfo_int80)=20
- );
/* If we're using memcheck, use this intercept right from the
start, otherwise ld.so (glibc-2.3.5) makes a lot of noise. */
if (0=3D=3DVG_(strcmp)("Memcheck", VG_(details).name)) {
@@ -827,8 +824,25 @@
/*--- NOTIFY-ON-LOAD FUNCTIONS ---*/
/*------------------------------------------------------------*/
=20
-static void handle_maybe_load_notifier( HChar* symbol, Addr addr )
+static=20
+void handle_maybe_load_notifier( const UChar* soname,=20
+ HChar* symbol, Addr addr )
{
+# if defined(VGP_x86_linux)
+ /* x86-linux only: if we see _dl_sysinfo_int80, note its address.
+ See comment on declaration of VG_(client__dl_sysinfo_int80) for
+ the reason. As far as I can tell, the relevant symbol is always
+ in object with soname "ld-linux.so.2". */
+ if (symbol && symbol[0] =3D=3D '_'=20
+ && 0 =3D=3D VG_(strcmp)(symbol, "_dl_sysinfo_int80")
+ && 0 =3D=3D VG_(strcmp)(soname, "ld-linux.so.2")) {
+ if (VG_(client__dl_sysinfo_int80) =3D=3D 0)
+ VG_(client__dl_sysinfo_int80) =3D addr;
+ }
+# endif
+
+ /* Normal load-notifier handling after here. First, ignore all
+ symbols lacking the right prefix. */
if (0 !=3D VG_(strncmp)(symbol, VG_NOTIFY_ON_LOAD_PREFIX,=20
VG_NOTIFY_ON_LOAD_PREFIX_LEN))
/* Doesn't have the right prefix */
@@ -836,9 +850,6 @@
=20
if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(freeres))) =3D=
=3D 0)
VG_(client___libc_freeres_wrapper) =3D addr;
-// else
-// if (VG_(strcmp)(symbol, STR(VG_WRAPPER(pthread_startfunc_wrapper))) =3D=
=3D 0)
-// VG_(pthread_startfunc_wrapper)((Addr)(si->offset + sym->st_value))=
;
else
vg_assert2(0, "unrecognised load notification function: %s", symbo=
l);
}
Modified: trunk/coregrind/m_signals.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_signals.c 2006-04-29 18:01:46 UTC (rev 5867)
+++ trunk/coregrind/m_signals.c 2006-04-29 18:03:14 UTC (rev 5868)
@@ -905,9 +905,11 @@
vg_assert(VG_(is_valid_tid)(tid));
tst =3D & VG_(threads)[tid];
=20
- if (VG_(clo_trace_signals))
+ if (VG_(clo_trace_signals)) {
VG_(message)(Vg_DebugMsg,=20
"push_signal_frame (thread %d): signal %d", tid, sigNo);
+ VG_(get_and_pp_StackTrace)(tid, 10);
+ }
=20
if (/* this signal asked to run on an alt stack */
(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_ONSTACK )
Modified: trunk/coregrind/m_stacktrace.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_stacktrace.c 2006-04-29 18:01:46 UTC (rev 5867)
+++ trunk/coregrind/m_stacktrace.c 2006-04-29 18:03:14 UTC (rev 5868)
@@ -38,6 +38,7 @@
#include "pub_core_machine.h"
#include "pub_core_options.h"
#include "pub_core_stacktrace.h"
+#include "pub_core_clientstate.h" // VG_(client__dl_sysinfo_int80)
#include "pub_core_trampoline.h"
=20
/*------------------------------------------------------------*/
@@ -344,16 +345,26 @@
Addr stack_highest_word =3D VG_(threads)[tid].client_stack_highest_wo=
rd;
=20
# if defined(VGP_x86_linux)
- /* Nasty little hack to deal with sysinfo syscalls - if libc is
- using the sysinfo page for syscalls (the TLS version does), then
- ip will always appear to be in that page when doing a syscall,
- not the actual libc function doing the syscall. This check sees
- if IP is within the syscall code, and pops the return address
- off the stack so that ip is placed within the library function
- calling the syscall. This makes stack backtraces much more
- useful. */
- if (ip >=3D (Addr)&VG_(trampoline_stuff_start)=20
- && ip < (Addr)&VG_(trampoline_stuff_end)
+ /* Nasty little hack to deal with syscalls - if libc is using its
+ _dl_sysinfo_int80 function for syscalls (the TLS version does),
+ then ip will always appear to be in that function when doing a
+ syscall, not the actual libc function doing the syscall. This
+ check sees if IP is within that function, and pops the return
+ address off the stack so that ip is placed within the library
+ function calling the syscall. This makes stack backtraces much
+ more useful.
+
+ The function is assumed to look like this (from glibc-2.3.6 source=
s):
+ _dl_sysinfo_int80:
+ int $0x80
+ ret
+ That is 3 (2+1) bytes long. We could be more thorough and check
+ the 3 bytes of the function are as expected, but I can't be
+ bothered.
+ */
+ if (VG_(client__dl_sysinfo_int80) !=3D 0 /* we know its address */
+ && ip >=3D VG_(client__dl_sysinfo_int80)
+ && ip < VG_(client__dl_sysinfo_int80)+3
&& VG_(am_is_valid_for_client)(sp, sizeof(Addr), VKI_PROT_READ)) =
{
ip =3D *(Addr *)sp;
sp +=3D sizeof(Addr);
Modified: trunk/coregrind/m_trampoline.S
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_trampoline.S 2006-04-29 18:01:46 UTC (rev 5867)
+++ trunk/coregrind/m_trampoline.S 2006-04-29 18:03:14 UTC (rev 5868)
@@ -55,7 +55,9 @@
.global VG_(x86_linux_SUBST_FOR_sigreturn)
VG_(x86_linux_SUBST_FOR_sigreturn):
/* This is a very specific sequence which GDB uses to
- recognize signal handler frames. */
+ recognize signal handler frames. Also gcc: see
+ x86_fallback_frame_state() in
+ gcc-4.1.0/gcc/config/i386/linux-unwind.h */
popl %eax
movl $__NR_sigreturn, %eax
int $0x80
@@ -68,12 +70,6 @@
int $0x80
ud2
=20
-.global VG_(x86_linux_REDIR_FOR__dl_sysinfo_int80)
-VG_(x86_linux_REDIR_FOR__dl_sysinfo_int80):
- /* We can point our sysinfo stuff here */
- int $0x80
- ret
-
/* There's no particular reason that this needs to be handwritten
assembly, but since that's what this file contains, here's a
simple index implementation (written in C and compiled by gcc.)
Modified: trunk/coregrind/pub_core_clientstate.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/pub_core_clientstate.h 2006-04-29 18:01:46 UTC (rev 5=
867)
+++ trunk/coregrind/pub_core_clientstate.h 2006-04-29 18:03:14 UTC (rev 5=
868)
@@ -82,6 +82,13 @@
/* Where is the __libc_freeres_wrapper routine we made? */
extern Addr VG_(client___libc_freeres_wrapper);
=20
+/* x86-linux only: where is ld.so's _dl_sysinfo_int80 function?
+ Finding it isn't essential, but knowing where it is does sometimes
+ help produce better back traces. See big comment in
+ VG_(get_StackTrace) in m_stacktrace.c for further info. */
+extern Addr VG_(client__dl_sysinfo_int80);
+
+
#endif // __PUB_CORE_CLIENTSTATE_H
=20
/*--------------------------------------------------------------------*/
Modified: trunk/coregrind/pub_core_trampoline.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/pub_core_trampoline.h 2006-04-29 18:01:46 UTC (rev 58=
67)
+++ trunk/coregrind/pub_core_trampoline.h 2006-04-29 18:03:14 UTC (rev 58=
68)
@@ -37,6 +37,15 @@
// stubs for signal returns. Note, all the code within runs on the
// simulated CPU. The vsyscall stubs are gotten to by use of the=20
// redirect mechanism.
+//
+// Note: generally, putting replacement functions in here is a bad
+// idea, since any Dwarf frame-unwind info attached to them will not
+// be seen by the unwinder in gcc's runtime support. This means
+// unwinding during exception handling by gcc tends to fail if it
+// encounters one of these replacement functions. A better place to
+// put them is in one of the .so's preloaded into the client, since
+// the client's ld.so will know about it and so gcc's unwinder
+// (somehow) is able to get hold of it.
//--------------------------------------------------------------------
=20
/* These two delimit our handwritten assembly code, so we can tell
@@ -50,7 +59,6 @@
#if defined(VGP_x86_linux)
extern void VG_(x86_linux_SUBST_FOR_sigreturn);
extern void VG_(x86_linux_SUBST_FOR_rt_sigreturn);
-extern void VG_(x86_linux_REDIR_FOR__dl_sysinfo_int80);
extern Char* VG_(x86_linux_REDIR_FOR_index) ( const Char*, Int );
#endif
=20
|