|
From: Julian S. <js...@ac...> - 2006-02-07 01:23:57
|
Eric
> I've just been trying to make Wine run under valgrind (3.1.0). Things
> greately evolved since our last tries: we can now run lots of
> applications, and a major part of our test suite under valgrind.
> congrats folks!!
That's great. In an ideal world we could make Wine run really well
under V and then be able to use V to debug Windows apps. Adam Gundy
did this a couple of years ago, but the required changes were never
merged in.
> I've posted two patches in bugzilla to improve some parts, which
> hopefully can make for 3.2.0.
Uh ... where did you post these, exactly? Can you send a URL ?
> What doesn't currently work in valgrind is changing the EIP in the
> sigcontext. Current implementation of restore_sigcontext() in
> coregrind/m_sigframe/sigframe-x86-linux.c doesn't restore EIP into VEX:
> when we return from the signal handler, execution resumes at the opcode
> with first generated the signal. Back to square one :-/
Sun's JVM also does nasty tricks like this, and I think Tom Hughes
got the same bad-opcode result when he tried restoring EIP into vex.
I would like to fix it for Java folks too.
> I simply tried to set EIP back in the restore_sigcontext() function, but
> this leads to a crash in IR (about unsupported opcode).
Hmm. Doing that works OK at least for my simple test program
on SuSE 10 (x86):
$ vTRUNK --trace-signals=yes --tool=none ./sig_change_pc
[...]
--1237-- Max kernel-supported signal is 64
++1237++ sys_sigaction: sigNo 40, new 0xBEB86D18, old 0x0, new flags 0x4000004
before
--1237-- kill: sent signal 40 to pid 1237
--1237-- poll_signals: got signal 40 for thread 1
--1237-- Polling found signal 40 for tid 1
--1237-- delivering signal 40 (SIGRT8):0 to thread 1
--1237-- push_signal_frame (thread 1): signal 40
in handler, setting EIP to 0x8048588
returned EIP is 0x8048588
--1237-- VG_(signal_return) (thread 1): isRT=1 valid magic; EIP=0x8048588
diversion!
==1237==
Test program is below. It also works correctly if I uncomment the
two commented-out bits, so as to get a segfault instead. The relevant
valgrind diff (against current svn head, versions 5616/1570) is:
Index: coregrind/m_sigframe/sigframe-x86-linux.c
===================================================================
--- coregrind/m_sigframe/sigframe-x86-linux.c (revision 5616)
+++ coregrind/m_sigframe/sigframe-x86-linux.c (working copy)
@@ -630,8 +630,8 @@
tst->arch.vex.guest_ESI = sc->esi;
tst->arch.vex.guest_EDI = sc->edi;
//:: tst->arch.vex.guest_eflags = sc->eflags;
-//:: tst->arch.vex.guest_EIP = sc->eip;
-
+ VG_(printf)("returned EIP is %p\n", sc->eip);
+ tst->arch.vex.guest_EIP = sc->eip;
tst->arch.vex.guest_CS = sc->cs;
tst->arch.vex.guest_SS = sc->ss;
tst->arch.vex.guest_DS = sc->ds;
> I suppose I'm
> missing something (like resetting some other elements for execution in
> some other places). Anything I could do about this ?
Does this work for you? I'd like to help but obviously I need to be
able to reproduce the problem first.
J
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <assert.h>
#define __USE_GNU
#include <sys/ucontext.h>
void diversion ( void )
{
printf("diversion!\n");
exit(0);
}
void handler ( int signo, siginfo_t* info, void* ctxV )
{
ucontext_t* ctx = (ucontext_t*)ctxV;
printf("in handler, setting EIP to %p\n", (void*)&diversion);
ctx->uc_mcontext.gregs[REG_EIP] = (unsigned long)&diversion;
}
int main ( void )
{
int r;
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_sigaction = handler;
act.sa_flags = SA_SIGINFO;
sigemptyset(&act.sa_mask);
r = sigaction(/*SIGSEGV*/40, &act, NULL);
assert(r == 0);
printf("before\n");
kill( getpid(), 40 );
/* *(int*)1 = 1; */
printf("after -- SHOULD NOT SEE THIS\n");
return 0;
}
|