Bug 869184

Summary: trouble debugging 32bit program on ppc64 via valgrind gdb server
Product: Red Hat Developer Toolset Reporter: Miroslav Franc <mfranc>
Component: valgrindAssignee: Mark Wielaard <mjw>
Status: CLOSED WONTFIX QA Contact:
Severity: medium Docs Contact:
Priority: unspecified    
Version: DTS 1.1 RHEL 6CC: fche, jakub, mcermak, mfranc, mnewsome, ohudlick
Target Milestone: rc   
Target Release: 1.1   
Hardware: ppc64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Known Issue
Doc Text:
Cause: The default (--vgdb=yes) valgrind gdbserver support is fairly lightweight, but might cause some registers and flags values to not always be up to date due to the optimisations done by the Valgrind core. Consequence: gdb is unable to show some parameters or variables on a breakpoint or when single stepping the program running under valgrind. Workaround (if any): Use valgrind --vgdb=full. Result: Better gdb debugging experience, but (much) slower program run under valgrind. See also the upstream manual as quoted in comment #2 with a somewhat subtler workaround for this particular case.
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-10-29 22:26:01 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Miroslav Franc 2012-10-23 08:37:30 UTC
Description of problem:
I have trouble accessing variables when debugging -m32 compiled program with valgrind gdb server.  I was unable to reproduce with gdb-gdbserver, that's why I'm filing this against valgrind. Happens on both RHEL5 and RHEL6.


Version-Release number of selected component (if applicable):
devtoolset-1.1-valgrind-3.8.1-3.2.el6.ppc64
devtoolset-1.1-valgrind-openmpi-3.8.1-3.2.el6.ppc64
devtoolset-1.1-valgrind-devel-3.8.1-3.2.el6.ppc64
devtoolset-1.1-valgrind-3.8.1-3.2.el6.ppc
devtoolset-1.1-valgrind-openmpi-3.8.1-3.2.el6.ppc
devtoolset-1.1-valgrind-devel-3.8.1-3.2.el6.ppc


How reproducible:

--- something.c ---
#include <stdio.h>

void f (int x);

int
main (int argc, char *argv[])
{
  int a;

  f(a);

  return 0;
}

void
f (int x)
{
  static int var __attribute__ ((used)) = 42;
  if(x)
    puts("hello, world");
}
--- something.c ---


Steps to Reproduce:
1. gcc -m32 -g something.c
2. valgrind --vgdb-error=0 ./a.out
3. gdb ./a.out
4. (gdb) target remote | vgdb
5. (gdb) b 10
6. (gdb) c


Actual results:
Breakpoint 1, main (argc=<error reading variable: Cannot access memory at address 0x18>, argv=<error reading variable: Cannot access memory at address 0x1c>) at something.c:10


Expected results:
Breakpoint 1, main (argc=1, argv=0xfffef1c4) at something.c:10

Comment 2 Mark Wielaard 2012-10-29 21:19:25 UTC
This seems to be caused by some optimizations done by the valgrind core when using the minimal gdbserver. See http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver-limitations

"Processor registers and flags values.

When Valgrind gdbserver stops on an error, on a breakpoint or when single stepping, registers and flags values might not be always up to date due to the optimisations done by the Valgrind core. The default value --vex-iropt-register-updates=unwindregs-at-mem-access ensures that the registers needed to make a stack trace (typically PC/SP/FP) are up to date at each memory access (i.e. memory exception points). Disabling some optimisations using the following values will increase the precision of registers and flags values (a typical performance impact for memcheck is given for each option).

    --vex-iropt-register-updates=allregs-at-mem-access (+10%) ensures that all registers and flags are up to date at each memory access.
    --vex-iropt-register-updates=allregs-at-each-insn (+25%) ensures that all registers and flags are up to date at each instruction.

Note that --vgdb=full (+500%, see above Precision of "stop-at" commands) automatically activates --vex-iropt-register-updates=allregs-at-each-insn."

Using either --vex-iropt-register-updates=allregs-at-mem-access or --vgdb=full will make the example work as expected:

$ valgrind --vex-iropt-register-updates=allregs-at-mem-access --vgdb-error=0 ./a.out

$ gdb ./a.out
(gdb) target remote | vgdb
(gdb) b 10
Breakpoint 1 at 0x10000498: file something.c, line 10.
(gdb) c
Continuing.

Breakpoint 1, main (argc=1, argv=0xfeccf1e4) at something.c:10
10	  f(a);

Comment 3 Mark Wielaard 2012-10-29 21:22:09 UTC
Since this is a known limitation and has a known workaround, I suggest we just document this. Unless people think making --vex-iropt-register-updates=allregs-at-mem-access the default on ppc is a better idea (this would imply a 10% slowdown in the default case, so I am not recommending it).

Comment 4 RHEL Program Management 2012-10-29 22:26:01 UTC
Development Management has reviewed and declined this request.
You may appeal this decision by reopening this request.