|
From: Maynard J. <may...@us...> - 2011-10-31 15:34:01
|
On 10/28/2011 6:01 PM, Philippe Waroquiers wrote:
>
>> Back on the SLES 11 SP1/POWER7 system, a fresh pull of upstream valgrind ran
>> quite well this time -- no hangs in the gdbserver tests,
>> and I still get the same three testcases failing: mcbreak, mcinfcallRU, and
>> mcinfcallWSRU. Again, the *.out files you asked for are attached.
>
> In the 'no extra options' file, we see that mcbreak fails when gdb invokes a
> function call.
> A break is encountered in t.c at line 112.
> The test executes a few "steps" and a "next"
> and then invokes a call to whoami("first").
> We see in mcbreak.stderr.out.unfiltered.out that the process crashes due to the
> following error:
> ==63162== Process terminating with default action of signal 11 (SIGSEGV):
> dumping core
> ==63162== Bad permissions for mapped region at address 0x10012030
> ==63162== at 0x10000BB0: whoami (t.c:28)
> ==63162== by 0x10001183: main (t.c:112)
> The two other tests are also failing with a similar 'Bad permissions'. The
> address however slightly changes.
>
>
> If we examine more in details mcbreak.stderr.out.unfiltered.out (searching for
> signal 11),
> we see some lines above the following:
> --63758:1:gdbsrv stop_pc 0x10001194 changed to be resume_pc 0x401F4D0: malloc
> (dl-minimal.c:96)
>
> gdbsrv indicates that gdb has asked to change the pc at which the process was
> stopped (somewhere around t.c:112)
> to be another pc (the pc of malloc). This is because gdb must allocate memory in
> order to execute the whoami("first") :
> it first has to allocate memory by "pushing" a call to malloc.
> gdb has then to copy "first" in this memory, and it can then pushes a call to
> whoami.
>
> The usual technique with which gdb pushes a call is:
> It puts a break instruction somewhere (gdb has some logic depending on the OS
> and/or processor to find a "reasonable" place
> where such a break can be put).
> It then pushes the address where this break has been put as a return address
> (the technique to put the return address
> depends on the ABI. IIRC, on power, this is via a register)
> It puts the needed arguments
> and then invokes the function to call (e.g. malloc, or whoami, or ...) by
> changing the pc to be the pc of this function.
> When this function returns, it returns to the break instruction. The break
> causes gdb to regain control.
> gdb then knows the function call is finished. It recuperates the return value
> (e.g. what malloc has returned)
> and can continue.
>
> From what I can see, gdb uses the address 0x10012030 to put the break.
> It then calls malloc. But this malloc calls already fails (gives a signal 11).
> It looks like gdb believes the call has worked
> properly, as it then pushes a call to whoami.
>
> I do not know why the calls to malloc fails, and why the subsequent calls to
> whoami similarly fails.
>
> What could be done to investigate is to make a simpler test of invoking a
> function call.
> For example (not compiled):
> #include <stdio.h>
> int fun_set_me = 0;
> void fun (int i)
> {
> fun_set_me = i;
> }
> main()
> {
> printf ("hello world\n");
> printf ("fun_set_me %d\n", fun_set_me); <<< put a break here, then when
> encountered, call fun(1234) from gdb
> }
>
> Execute the above test on a f16/power7 valgrind with -v -v -v -d -d -d and gdb
> Do the same on suse.
> The difference in the trace between the two runs might explain what goes wrong
> on f16.
Actually, these tests run OK on F16, but fail on SLES 11 SP1. When running on
F16, the stdout and stderr output (both redirected to one file) show the "hello
world" and the "fun_set_me 1234" print outs. But I don't see either of these
when I run the same thing on SLES 11 SP1. I don't really know what to look for
to see where things go bad. I've attached both files in a tar file. Thanks for
your help!
-Maynard
>
> You might also compare the behaviour of the standard f16 gdbserver to the
> Valgrind gdbserver:
> The standard gdbserver has two options --debug and --remote-debug that will show
> the trace.
> This might also allow to compare a working function call invocation to the
> failing one under valgrind.
> The gdbserver protocol is relatively simple : the query packets and reply
> packets are explained in
> annex D of the gdb user manual. Note however that there will not be a one to one
> mapping between
> the packets exchange. E.g. gdb might send "Z" packets to insert "hardware
> breakpoints" to the
> Valgrind gdbserver (as valgrind gdbserver pretends it can implement hw
> watchpoint), and the standard
> gdbserver might indicate it only accepts breakpoints via chaning the instruction
> to a trap.
> But it should be possible to recognise the "push a call sequence".
>
> Hope the above helps ...
>
> Philippe
>
|