|
From: Alex B. <ker...@be...> - 2006-11-15 16:11:27
|
Hi,
I have a program that seems to be behaving differently in valgrind
(latest SVN code) to being run normally. My program has a signal handler
which to handle integer overflow conditions. The code looks roughly
like:
void arithmeticSigHandler(int sigNum, siginfo_t *siginfo, void *stuff)
{
ucontext_t *uctx = (ucontext_t *)stuff;
mcontext_t *ctx = (mcontext_t *)&(uctx->uc_mcontext);
//
// Read the faulting instruction so we can check if the fault was
// a signed or unsigned divide.
//
unsigned char instOpcode = *((char*)ctx->gregs[REG_RIP]);
unsigned char instModRM = *((char*)(ctx->gregs[REG_RIP]+1));
fp fprintf(stderr,"rip 0x%lx: instOpcode = 0x%x, ModRM = 0x%x\n",
ctx->gregs[REG_RIP], instOpcode, instModRM);
if(instOpcode == 0xF7) // check its a divide
{
However under valgrind it fails the check and falls through to some
debug code for bad SIGFPE's. The run with the fprintf give the following
output:
Test 5
rip 0x702277f2: instOpcode = 0x8b, ModRM = 0x55
==15666==
==15666== Uninitialised byte(s) found during client check request
But attaching to gdb at the point it gets confused:
...
#15 0x00000000702dbb9f in arithmeticSigHandler (sigNum=8,
siginfo=0x2a960108c8, stuff=0x2a96010798)
#16 <signal handler called>
#17 0x00000000702277f5 in subjectInterpreter_sdiv ()
(gdb) frame 17
#17 0x00000000702277f5 in subjectInterpreter_sdiv ()
(gdb) x/1i $pc
0x702277f5 <subjectInterpreter_sdiv>: idiv %ebx
(gdb) x/5b $pc
0x702277f5 <subjectInterpreter_sdiv>: 0xf7 0xfb 0x89 0x45
0xf0
It looks like the pc the valgrind supplies is a few bytes off what the
core would indicate (and what would happen in real life).
(gdb) x/5b 0x702277f2
0x702277f2: 0x8b 0x55 0xe8 0xf7 0xfb
Any ideas what could be causing that?
I'm running valgrind with the following options:
/usr/local/bin/valgrind --leak-check=full
--vex-iropt-precise-memory-exns --smc-check=all --db-attach=yes
--db-command="/usr/local/bin/gdb -nw %f %p"
For completeness running outside of valgrind I get:
Test 5
rip 0x702277f5: instOpcode = 0xf7, ModRM = 0xfb
Which behaves as expected.
--
Alex, homepage: http://www.bennee.com/~alex/
Think big. Pollute the Mississippi.
|
|
From: Julian S. <js...@ac...> - 2006-11-16 00:28:02
|
Looks to me like V is not giving you precise exceptions w.r.t.
your division instruction. I am not sure I made complete sense of
your gdb workings, but I think what you are saying is when running
on V the pc of the faulting insn offered by the signal handler is
3 bytes too late. Right?
Does --vex-iropt-level=0 make it work right? That might give
a whole bunch of false positives, but let's deal with one thing
at a time.
J
On Wednesday 15 November 2006 16:11, Alex Bennee wrote:
> Hi,
>
> I have a program that seems to be behaving differently in valgrind
> (latest SVN code) to being run normally. My program has a signal handler
> which to handle integer overflow conditions. The code looks roughly
> like:
>
> void arithmeticSigHandler(int sigNum, siginfo_t *siginfo, void *stuff)
> {
> ucontext_t *uctx = (ucontext_t *)stuff;
> mcontext_t *ctx = (mcontext_t *)&(uctx->uc_mcontext);
>
> //
> // Read the faulting instruction so we can check if the fault was
> // a signed or unsigned divide.
> //
> unsigned char instOpcode = *((char*)ctx->gregs[REG_RIP]);
> unsigned char instModRM = *((char*)(ctx->gregs[REG_RIP]+1));
>
> fp fprintf(stderr,"rip 0x%lx: instOpcode = 0x%x, ModRM = 0x%x\n",
> ctx->gregs[REG_RIP], instOpcode, instModRM);
>
> if(instOpcode == 0xF7) // check its a divide
> {
>
> However under valgrind it fails the check and falls through to some
> debug code for bad SIGFPE's. The run with the fprintf give the following
> output:
>
> Test 5
> rip 0x702277f2: instOpcode = 0x8b, ModRM = 0x55
> ==15666==
> ==15666== Uninitialised byte(s) found during client check request
>
>
> But attaching to gdb at the point it gets confused:
>
> ...
> #15 0x00000000702dbb9f in arithmeticSigHandler (sigNum=8,
> siginfo=0x2a960108c8, stuff=0x2a96010798)
> #16 <signal handler called>
> #17 0x00000000702277f5 in subjectInterpreter_sdiv ()
>
> (gdb) frame 17
> #17 0x00000000702277f5 in subjectInterpreter_sdiv ()
> (gdb) x/1i $pc
> 0x702277f5 <subjectInterpreter_sdiv>: idiv %ebx
> (gdb) x/5b $pc
> 0x702277f5 <subjectInterpreter_sdiv>: 0xf7 0xfb 0x89 0x45
> 0xf0
>
> It looks like the pc the valgrind supplies is a few bytes off what the
> core would indicate (and what would happen in real life).
>
>
> (gdb) x/5b 0x702277f2
> 0x702277f2: 0x8b 0x55 0xe8 0xf7 0xfb
>
> Any ideas what could be causing that?
>
> I'm running valgrind with the following options:
>
> /usr/local/bin/valgrind --leak-check=full
> --vex-iropt-precise-memory-exns --smc-check=all --db-attach=yes
> --db-command="/usr/local/bin/gdb -nw %f %p"
>
>
> For completeness running outside of valgrind I get:
> Test 5
> rip 0x702277f5: instOpcode = 0xf7, ModRM = 0xfb
>
>
> Which behaves as expected.
|
|
From: Alex B. <ker...@be...> - 2006-11-16 11:59:37
|
On Thu, 2006-11-16 at 00:36 +0000, Julian Seward wrote:
> Looks to me like V is not giving you precise exceptions w.r.t.
> your division instruction. I am not sure I made complete sense of
> your gdb workings, but I think what you are saying is when running
> on V the pc of the faulting insn offered by the signal handler is
> 3 bytes too late. Right?
Other way round. The pc offered to the signal handler in while running
in V is 3 bytes too early. However the core V presents to GDB when
attaching shows the backtrace at the faulting is in the right place.
> Does --vex-iropt-level=0 make it work right? That might give
> a whole bunch of false positives, but let's deal with one thing
> at a time.
Yes. With that option enabled the pc the signal handler gets is correct
and it follows the correct path in the code.
>
> J
>
>
> On Wednesday 15 November 2006 16:11, Alex Bennee wrote:
> > Hi,
> >
> > I have a program that seems to be behaving differently in valgrind
> > (latest SVN code) to being run normally. My program has a signal handler
> > which to handle integer overflow conditions. The code looks roughly
> > like:
> >
> > void arithmeticSigHandler(int sigNum, siginfo_t *siginfo, void *stuff)
> > {
> > ucontext_t *uctx = (ucontext_t *)stuff;
> > mcontext_t *ctx = (mcontext_t *)&(uctx->uc_mcontext);
> >
> > //
> > // Read the faulting instruction so we can check if the fault was
> > // a signed or unsigned divide.
> > //
> > unsigned char instOpcode = *((char*)ctx->gregs[REG_RIP]);
> > unsigned char instModRM = *((char*)(ctx->gregs[REG_RIP]+1));
> >
> > fp fprintf(stderr,"rip 0x%lx: instOpcode = 0x%x, ModRM = 0x%x\n",
> > ctx->gregs[REG_RIP], instOpcode, instModRM);
> >
> > if(instOpcode == 0xF7) // check its a divide
> > {
> >
> > However under valgrind it fails the check and falls through to some
> > debug code for bad SIGFPE's. The run with the fprintf give the following
> > output:
> >
> > Test 5
> > rip 0x702277f2: instOpcode = 0x8b, ModRM = 0x55
> > ==15666==
> > ==15666== Uninitialised byte(s) found during client check request
> >
> >
> > But attaching to gdb at the point it gets confused:
> >
> > ...
> > #15 0x00000000702dbb9f in arithmeticSigHandler (sigNum=8,
> > siginfo=0x2a960108c8, stuff=0x2a96010798)
> > #16 <signal handler called>
> > #17 0x00000000702277f5 in subjectInterpreter_sdiv ()
> >
> > (gdb) frame 17
> > #17 0x00000000702277f5 in subjectInterpreter_sdiv ()
> > (gdb) x/1i $pc
> > 0x702277f5 <subjectInterpreter_sdiv>: idiv %ebx
> > (gdb) x/5b $pc
> > 0x702277f5 <subjectInterpreter_sdiv>: 0xf7 0xfb 0x89 0x45
> > 0xf0
> >
> > It looks like the pc the valgrind supplies is a few bytes off what the
> > core would indicate (and what would happen in real life).
> >
> >
> > (gdb) x/5b 0x702277f2
> > 0x702277f2: 0x8b 0x55 0xe8 0xf7 0xfb
> >
> > Any ideas what could be causing that?
> >
> > I'm running valgrind with the following options:
> >
> > /usr/local/bin/valgrind --leak-check=full
> > --vex-iropt-precise-memory-exns --smc-check=all --db-attach=yes
> > --db-command="/usr/local/bin/gdb -nw %f %p"
> >
> >
> > For completeness running outside of valgrind I get:
> > Test 5
> > rip 0x702277f5: instOpcode = 0xf7, ModRM = 0xfb
> >
> >
> > Which behaves as expected.
>
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share your
> opinions on IT & business topics through brief surveys - and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> _______________________________________________
> Valgrind-users mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
--
Alex, homepage: http://www.bennee.com/~alex/
You can only live once, but if you do it right, once is enough.
|
|
From: Julian S. <js...@ac...> - 2006-11-16 12:01:31
|
> > Does --vex-iropt-level=0 make it work right? That might give > > a whole bunch of false positives, but let's deal with one thing > > at a time. > > Yes. With that option enabled the pc the signal handler gets is correct > and it follows the correct path in the code. So how important is this? Is it worth fixing properly? J |
|
From: Alex B. <ker...@be...> - 2006-11-16 17:43:00
|
On Thu, 2006-11-16 at 12:10 +0000, Julian Seward wrote: > > > Does --vex-iropt-level=0 make it work right? That might give > > > a whole bunch of false positives, but let's deal with one thing > > > at a time. > > > > Yes. With that option enabled the pc the signal handler gets is correct > > and it follows the correct path in the code. > > So how important is this? Is it worth fixing properly? Well it caused mucho confusion but I now have a work around I can use in other cases that look wierd. Perhaps disabling for precise mode would be worthwhile though. > > J > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys - and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > Valgrind-users mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-users -- Alex, homepage: http://www.bennee.com/~alex/ All theoretical chemistry is really physics; and all theoretical chemists know it. -- Richard P. Feynman |
|
From: Tom H. <to...@co...> - 2006-11-16 12:14:26
|
In message <116...@ok...>
Alex Bennee <ker...@be...> wrote:
> On Thu, 2006-11-16 at 00:36 +0000, Julian Seward wrote:
>> Looks to me like V is not giving you precise exceptions w.r.t.
>> your division instruction. I am not sure I made complete sense of
>> your gdb workings, but I think what you are saying is when running
>> on V the pc of the faulting insn offered by the signal handler is
>> 3 bytes too late. Right?
>
> Other way round. The pc offered to the signal handler in while running
> in V is 3 bytes too early. However the core V presents to GDB when
> attaching shows the backtrace at the faulting is in the right place.
I don't see how that can be - as far as I can see they both use the
value of arch.vex.guest_RIP from the thread state.
If you use --trace-signals=yes what EIP values does valgrind report
when delivering the signal?
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|
|
From: Julian S. <js...@ac...> - 2006-11-16 12:31:41
|
> I don't see how that can be - as far as I can see they both use the > value of arch.vex.guest_RIP from the thread state. That's true, but the problem is that vex's redundant-Put removal pass optimises away updates to guest_RIP if a later instruction in the block sets it (which of course all insns in the block do) _and_ if it does not believe there could be an exception for the current instruction which could cause some outside agent (eg, a signal handler) to look at guest_RIP. Problem is the bit after _and_: Vex does not take into account the possibility that the division insn could fault. One easy, if performance-reducing fix is to disable redundant-Put removal if --vex-guest-precise-mem-exns is specified. Having a less stupid flag name would be no bad thing either :-) J |
|
From: Tom H. <to...@co...> - 2006-11-16 13:05:54
|
In message <200...@ac...>
Julian Seward <js...@ac...> wrote:
>> I don't see how that can be - as far as I can see they both use the
>> value of arch.vex.guest_RIP from the thread state.
>
> That's true, but the problem is that vex's redundant-Put removal pass
> optimises away updates to guest_RIP if a later instruction in the
> block sets it (which of course all insns in the block do) _and_ if
> it does not believe there could be an exception for the current instruction
> which could cause some outside agent (eg, a signal handler) to look at
> guest_RIP.
>
> Problem is the bit after _and_: Vex does not take into account the
> possibility that the division insn could fault.
None of that explains why m_debugger/debugger.c is seeing a different
value for guest_RIP to m_sigframe/sigframe-amd64-linux.c though...
They should both presumably be running at the time that the fault
occurs and hence seeing the same state - the call to VG_(start_debugger)
is in default_action in m_signals.c so will happen at the time the
signal is delivered if there is no handler.
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|