From b37b05d214e7c74bfad3a622a79877418efec6d0 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Tue, 10 May 2011 11:01:07 +0000 Subject: [PATCH] Improvements for testing and compilation breakage for the GDB server on various platforms: * In all gdbserver_tests using gdb: Made a more general way to remove the initial start message. * tests using threads burning cpu modified to have only 1 thread. This makes them independent of the scheduler fairness. * filter_gdb and filter_vgdb enhanced to anonymise some debian 6.0/ppc specific things some s390x/gdb 7.0, gdb 7.1 specific things * vgdb.c: added an #include to fix compilation on s390x fedora and suse. (Christian Boerntrager) * fixed a bug in valgrind-low.c debug log : when a register size is 0, its image cannot be output (and register should not be transferred). * added a parameter --keep-unfiltered to vg_regtest.in This will make it easier to update filter_gdb: in case gdbserver_tests are failing due to "artificial" differences to be filtered, re-run the tests using: perl tests/vg_regtest --keep-unfiltered gdbserver_tests Then a tar file with all the *.out in gdbserver_tests will allow me to better/faster update the filter_gdb. * made a better detection of a working PTRACE_GETREGS at compile time and/or at run-time. This is the patch on bug 214909 comment 69. (Philippe Waroquiers, philippe.waroquiers@skynet.be) git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11740 --- coregrind/m_gdbserver/valgrind-low.c | 4 +- coregrind/vgdb.c | 163 +++++++++++++----- gdbserver_tests/filter_gdb | 21 ++- gdbserver_tests/filter_vgdb | 10 +- gdbserver_tests/mcbreak.stdinB.gdb | 1 + gdbserver_tests/mcbreak.stdoutB.exp | 2 - gdbserver_tests/mcbreak.vgtest | 2 + gdbserver_tests/mcclean_after_fork.stdinB.gdb | 1 + .../mcclean_after_fork.stdoutB.exp | 2 - gdbserver_tests/mcinfcallRU.stderr.exp | 5 +- gdbserver_tests/mcinfcallRU.stdinB.gdb | 1 + gdbserver_tests/mcinfcallRU.vgtest | 4 +- gdbserver_tests/mcinfcallWSRU.stderr.exp | 3 +- gdbserver_tests/mcinfcallWSRU.stderrB.exp | 13 +- gdbserver_tests/mcinfcallWSRU.stdinB.gdb | 1 + gdbserver_tests/mcinfcallWSRU.vgtest | 4 +- gdbserver_tests/mcleak.stdinB.gdb | 1 + gdbserver_tests/mcsignopass.stdinB.gdb | 1 + gdbserver_tests/mcsignopass.stdoutB.exp | 2 - gdbserver_tests/mcsigpass.stdinB.gdb | 1 + gdbserver_tests/mcsigpass.stdoutB.exp | 2 - gdbserver_tests/mcvabits.stdinB.gdb | 1 + gdbserver_tests/mcvabits.stdoutB.exp | 2 - gdbserver_tests/mcwatchpoints.stdinB.gdb | 1 + gdbserver_tests/mcwatchpoints.stdoutB.exp | 2 - gdbserver_tests/mssnapshot.stdinB.gdb | 1 + gdbserver_tests/mssnapshot.stdoutB.exp | 2 - gdbserver_tests/nlcontrolc.stdinB.gdb | 1 + gdbserver_tests/nlcontrolc.stdoutB.exp | 2 - gdbserver_tests/sleepers.c | 33 ++-- tests/vg_regtest.in | 32 +++- 31 files changed, 212 insertions(+), 109 deletions(-) diff --git a/coregrind/m_gdbserver/valgrind-low.c b/coregrind/m_gdbserver/valgrind-low.c index fc376fafe9..5d3f708434 100644 --- a/coregrind/m_gdbserver/valgrind-low.c +++ b/coregrind/m_gdbserver/valgrind-low.c @@ -176,7 +176,7 @@ void fetch_register (int regno) return; } size = register_size (regno); - { + if (size > 0) { Bool mod; char buf [size]; VG_(memset) (buf, 0, size); // registers not fetched will be seen as 0. @@ -225,7 +225,7 @@ void usr_store_inferior_registers (int regno) } size = register_size (regno); - { + if (size > 0) { Bool mod; Addr old_SP, new_SP; char buf[size]; diff --git a/coregrind/vgdb.c b/coregrind/vgdb.c index fffc7cc8d6..d5cacd3906 100644 --- a/coregrind/vgdb.c +++ b/coregrind/vgdb.c @@ -51,6 +51,7 @@ # if defined(VGO_linux) #include +#include # endif /* vgdb has two usages: @@ -624,67 +625,137 @@ void detach_from_all_threads(int pid) static int pid_of_save_regs = 0; static struct user user_save; +// The below indicates if ptrace_getregs (and ptrace_setregs) can be used. +// Note that some linux versions are defining PTRACE_GETREGS but using +// it gives back EIO. +// has_working_ptrace_getregs can take the following values: +// -1 : PTRACE_GETREGS is defined +// runtime check not yet done. +// 0 : PTRACE_GETREGS runtime check has failed. +// 1 : PTRACE_GETREGS defined and runtime check ok. +#ifdef PTRACE_GETREGS +static int has_working_ptrace_getregs = -1; +#endif + /* Get the registers from pid into regs. + regs_bsz value gives the length of *regs. Returns True if all ok, otherwise False. */ static -Bool getregs (int pid, void *regs) +Bool getregs (int pid, void *regs, long regs_bsz) { -# ifdef VGA_s390x - char *pregs = (char *) regs; - long offset; - errno = 0; - DEBUG(1, "getregs PTRACE_PEEKUSER(s)\n"); - for (offset = 0; offset < PT_ENDREGS; offset = offset + sizeof(long)) { - *(long *)(pregs+offset) = ptrace(PTRACE_PEEKUSER, pid, offset, NULL); - if (errno != 0) { - ERROR(errno, "PTRACE_PEEKUSER offset %ld\n", offset); + DEBUG(1, "getregs regs_bsz %ld\n", regs_bsz); +# ifdef PTRACE_GETREGS + if (has_working_ptrace_getregs) { + // Platforms having GETREGS + long res; + DEBUG(1, "getregs PTRACE_GETREGS\n"); + res = ptrace (PTRACE_GETREGS, pid, NULL, regs); + if (res == 0) { + if (has_working_ptrace_getregs == -1) { + // First call to PTRACE_GETREGS succesful => + has_working_ptrace_getregs = 1; + DEBUG(1, "detected a working PTRACE_GETREGS\n"); + } + assert (has_working_ptrace_getregs == 1); + return True; + } + else if (has_working_ptrace_getregs == 1) { + // We had a working call, but now it fails. + // This is unexpected. + ERROR(errno, "PTRACE_GETREGS %ld\n", res); return False; + } else { + // Check this is the first call: + assert (has_working_ptrace_getregs == -1); + if (errno == EIO) { + DEBUG(1, "detected a broken PTRACE_GETREGS with EIO\n"); + has_working_ptrace_getregs = 0; + // Fall over to the PTRACE_PEEKUSER case. + } else { + ERROR(errno, "broken PTRACE_GETREGS unexpected errno %ld\n", res); + return False; + } } } - return True; -# else - // Platforms having GETREGS - long res; - DEBUG(1, "getregs PTRACE_GETREGS\n"); - res = ptrace (PTRACE_GETREGS, pid, NULL, regs); - if (res != 0) { - ERROR(errno, "PTRACE_GETREGS %ld\n", res); - return False; - } - return True; # endif + + // We assume PTRACE_PEEKUSER is defined everywhere. + { +# ifdef PT_ENDREGS + long peek_bsz = PT_ENDREGS; + assert (peek_bsz <= regs_bsz); +# else + long peek_bsz = regs_bsz-1; +# endif + char *pregs = (char *) regs; + long offset; + errno = 0; + DEBUG(1, "getregs PTRACE_PEEKUSER(s) peek_bsz %ld\n", peek_bsz); + for (offset = 0; offset < peek_bsz; offset = offset + sizeof(long)) { + *(long *)(pregs+offset) = ptrace(PTRACE_PEEKUSER, pid, offset, NULL); + if (errno != 0) { + ERROR(errno, "PTRACE_PEEKUSER offset %ld\n", offset); + return False; + } + } + return True; + } + + // If neither PTRACE_GETREGS not PTRACE_PEEKUSER have returned, + // then we are in serious trouble. + assert (0); } /* Set the registers of pid to regs. + regs_bsz value gives the length of *regs. Returns True if all ok, otherwise False. */ static -Bool setregs (int pid, void *regs) +Bool setregs (int pid, void *regs, long regs_bsz) { -# ifdef VGA_s390x - char *pregs = (char *) regs; - long offset; - long res; - errno = 0; - DEBUG(1, "setregs PTRACE_POKEUSER(s)\n"); - for (offset = 0; offset < PT_ENDREGS; offset = offset + sizeof(long)) { - res = ptrace(PTRACE_POKEUSER, pid, offset, *(long*)(pregs+offset)); - if (errno != 0) { - ERROR(errno, "PTRACE_POKEUSER offset %ld res %ld\n", offset, res); + DEBUG(1, "setregs regs_bsz %ld\n", regs_bsz); +// Note : the below is checking for GETREGS, not SETREGS +// as if one is defined and working, the other one should also work. +# ifdef PTRACE_GETREGS + if (has_working_ptrace_getregs) { + // Platforms having SETREGS + long res; + // setregs can never be called before getregs has done a runtime check. + assert (has_working_ptrace_getregs == 1); + DEBUG(1, "setregs PTRACE_SETREGS\n"); + res = ptrace (PTRACE_SETREGS, pid, NULL, regs); + if (res != 0) { + ERROR(errno, "PTRACE_SETREGS %ld\n", res); return False; } + return True; } - return True; -# else - // Platforms having SETREGS - long res; - DEBUG(1, "setregs PTRACE_SETREGS\n"); - res = ptrace (PTRACE_SETREGS, pid, NULL, regs); - if (res != 0) { - ERROR(errno, "PTRACE_SETREGS %ld\n", res); - return False; - } - return True; # endif + + { + char *pregs = (char *) regs; + long offset; + long res; +# ifdef PT_ENDREGS + long peek_bsz = PT_ENDREGS; + assert (peek_bsz <= regs_bsz); +# else + long peek_bsz = regs_bsz-1; +# endif + errno = 0; + DEBUG(1, "setregs PTRACE_POKEUSER(s) %ld\n", peek_bsz); + for (offset = 0; offset < peek_bsz; offset = offset + sizeof(long)) { + res = ptrace(PTRACE_POKEUSER, pid, offset, *(long*)(pregs+offset)); + if (errno != 0) { + ERROR(errno, "PTRACE_POKEUSER offset %ld res %ld\n", offset, res); + return False; + } + } + return True; + } + + // If neither PTRACE_SETREGS not PTRACE_POKEUSER have returned, + // then we are in serious trouble. + assert (0); } /* Restore the registers to the saved value, then detaches from all threads */ @@ -701,7 +772,7 @@ void restore_and_detach(int pid) } DEBUG(1, "setregs restore registers pid %d\n", pid_of_save_regs); - if (!setregs(pid_of_save_regs, &user_save.regs)) { + if (!setregs(pid_of_save_regs, &user_save.regs, sizeof(user_save.regs))) { ERROR(errno, "setregs restore registers pid %d after cont\n", pid_of_save_regs); } @@ -757,7 +828,7 @@ Bool invoke_gdbserver (int pid) return False; } - if (!getregs(pid, &user_mod.regs)) { + if (!getregs(pid, &user_mod.regs, sizeof(user_mod.regs))) { detach_from_all_threads(pid); return False; } @@ -944,7 +1015,7 @@ Bool invoke_gdbserver (int pid) assert(0); } - if (!setregs(pid, &user_mod.regs)) { + if (!setregs(pid, &user_mod.regs, sizeof(user_mod.regs))) { detach_from_all_threads(pid); return False; } diff --git a/gdbserver_tests/filter_gdb b/gdbserver_tests/filter_gdb index 9dd7a3b4bc..90694703c1 100755 --- a/gdbserver_tests/filter_gdb +++ b/gdbserver_tests/filter_gdb @@ -14,6 +14,10 @@ $dir/filter_memcheck_monitor | # Anonymise or remove : +# delete the initial lines between the launch of vgdb and the +# output of the echo command telling it is launched. +# This removes a whole lot of uninteresting lines varying +# with OS/glibc/gdb dep # initial tty control character sent by gdb 7.0 # remove missing debuginfos # vgdb message @@ -23,7 +27,7 @@ $dir/filter_memcheck_monitor | # info threads output (e.g. which thread is running and syscall) # delete Reading symbols file lines # delete Loaded symbols file lines -# initial break message +# delete language switch messages. # remove gdb prompts. # remove gdb continuation prompts. # remove gdb done prompts. @@ -46,7 +50,8 @@ $dir/filter_memcheck_monitor | # a.o. produced by gdb 7.2 on arm (same with standard gdbserver) # delete empty lines (the last line (only made of prompts) sometimes # finishes with a new line, sometimes not ???). -sed -e 's/^\[?1034hReading symbols/Reading symbols/' \ +sed -e '/Remote debugging using/,/vgdb launched process attached/d' \ + -e 's/^\[?1034hReading symbols/Reading symbols/' \ -e '/Missing separate debuginfos, use: debuginfo-install/d' \ -e 's/\(relaying data between gdb and process \)[0-9][0-9]*/\1..../' \ -e 's/pid [0-9][0-9]*/pid ..../g' \ @@ -56,12 +61,8 @@ sed -e 's/^\[?1034hReading symbols/Reading symbols/' -e 's/#[0-9]\( 0x........ in sleeper_or_burner\)/#.\1/' \ -e '/^Reading symbols from .*\.\.\.done\./d' \ -e '/^Loaded symbols for .*$/d' \ - -e '1,8s/_start () from [^ ][^ ]*/_start () from ...start file.../' \ - -e '1,8s/\(0x........ in\) ?? () from \/lib\/ld-linux\.so\../\1 _start () from ...start file.../' \ - -e '1,8s/\(0x........ in\) ?? () from \/lib\/ld\.so\../\1 _start () from ...start file.../' \ - -e '1,8s/\(0x........ in\) ?? () from \/lib64\/ld64\.so\../\1 _start () from ...start file.../' \ - -e '1,8s/\(0x........ in\) ?? () from \/lib64\/ld-linux-x86-64\.so\../\1 _start () from ...start file.../' \ - -e '1,8s/\(0x........ in\) ?? ()$/\1 _start () from ...start file.../' \ + -e '/^Current language.*/d' \ + -e '/^The current source language is.*/d' \ -e 's/(gdb) //g' \ -e 's/^>[> ]*//' \ -e '/^done\.$/d' \ @@ -70,9 +71,13 @@ sed -e 's/^\[?1034hReading symbols/Reading symbols/' -e '/^ from \/lib\/ld-linux.so.*$/d' \ -e 's/\(0x........\) in ?? () from \/lib\/ld-linux\.so\../\1 in syscall .../' \ -e 's/\(0x........\) in ?? () from \/lib64\/tls\/libc\.so\../\1 in syscall .../' \ + -e 's/\(0x........\) in ?? ()$/\1 in syscall .../' \ -e 's/in \(.__\)\{0,1\}select () from \/.*$/in syscall .../' \ -e '/^ from \/lib\/libc.so.*$/d' \ + -e '/^ from \/lib64\/libc.so.*$/d' \ + -e '/^ from \/lib64\/tls\/libc.so.*$/d' \ -e 's/in select ()$/in syscall .../' \ + -e 's/in \.__select ()$/in syscall .../' \ -e 's/in select () at \.\.\/sysdeps\/unix\/syscall-template\.S.*$/in syscall .../' \ -e '/^[ ]*at \.\.\/sysdeps\/unix\/syscall-template\.S/d' \ -e '/^[ ]*in \.\.\/sysdeps\/unix\/syscall-template\.S/d' \ diff --git a/gdbserver_tests/filter_vgdb b/gdbserver_tests/filter_vgdb index 71b35119ec..2edc75a662 100755 --- a/gdbserver_tests/filter_vgdb +++ b/gdbserver_tests/filter_vgdb @@ -7,9 +7,11 @@ $dir/filter_stderr | # Anonymise addresses $dir/../tests/filter_addresses | -# filter vgdb process id, pid -# gdb 7.2 sometimes tries to access address 0x0 -# (same as with standard gdbserver) +# filter vgdb process id, +# pid +# gdb 7.2 sometimes tries to access address 0x0 (same as with standard gdbserver) +# filter a debian 6.0/ppc32 line sed -e 's/\(relaying data between gdb and process \)[0-9][0-9]*/\1..../' \ -e 's/\(sending command .* to pid \)[0-9][0-9]*/\1..../' \ - -e '/Cannot access memory at address 0x......../d' + -e '/Cannot access memory at address 0x......../d' \ + -e '/^[1-9][0-9]* \.\.\/sysdeps\/powerpc\/powerpc32\/dl-start\.S: No such file or directory\./d' diff --git a/gdbserver_tests/mcbreak.stdinB.gdb b/gdbserver_tests/mcbreak.stdinB.gdb index a154925617..19f3d86371 100644 --- a/gdbserver_tests/mcbreak.stdinB.gdb +++ b/gdbserver_tests/mcbreak.stdinB.gdb @@ -1,5 +1,6 @@ # connect gdb to Valgrind gdbserver: target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcbreak +echo vgdb launched process attached\n monitor vg.set vgdb-error 999999 # define checkstep diff --git a/gdbserver_tests/mcbreak.stdoutB.exp b/gdbserver_tests/mcbreak.stdoutB.exp index 2c51b39dff..e12d2e4483 100644 --- a/gdbserver_tests/mcbreak.stdoutB.exp +++ b/gdbserver_tests/mcbreak.stdoutB.exp @@ -1,5 +1,3 @@ -Remote debugging using | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcbreak -0x........ in _start () from ...start file... Breakpoint 1 at 0x........: file t.c, line 112. Breakpoint 2 at 0x........: file t.c, line 117. Continuing. diff --git a/gdbserver_tests/mcbreak.vgtest b/gdbserver_tests/mcbreak.vgtest index b79f41a151..41ea5e3c4a 100644 --- a/gdbserver_tests/mcbreak.vgtest +++ b/gdbserver_tests/mcbreak.vgtest @@ -3,9 +3,11 @@ prog: t vgopts: --tool=memcheck --vgdb=yes --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-mcbreak stdout_filter: filter_gdb +#stdout_filter: /bin/cat stderr_filter: filter_make_empty progB: gdb argsB: --quiet -l 60 --nx ./t stdinB: mcbreak.stdinB.gdb stdoutB_filter: filter_gdb +#stdoutB_filter: /bin/cat stderrB_filter: filter_memcheck_monitor diff --git a/gdbserver_tests/mcclean_after_fork.stdinB.gdb b/gdbserver_tests/mcclean_after_fork.stdinB.gdb index 145ad939ab..f91ca9e68b 100644 --- a/gdbserver_tests/mcclean_after_fork.stdinB.gdb +++ b/gdbserver_tests/mcclean_after_fork.stdinB.gdb @@ -1,5 +1,6 @@ # connect gdb to Valgrind gdbserver: target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcclean_after_fork +echo vgdb launched process attached\n monitor vg.set vgdb-error 999999 # # put a break in main, and then a watch diff --git a/gdbserver_tests/mcclean_after_fork.stdoutB.exp b/gdbserver_tests/mcclean_after_fork.stdoutB.exp index 8c6a8d37b7..6db3d3a2d5 100644 --- a/gdbserver_tests/mcclean_after_fork.stdoutB.exp +++ b/gdbserver_tests/mcclean_after_fork.stdoutB.exp @@ -1,5 +1,3 @@ -Remote debugging using | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcclean_after_fork -0x........ in _start () from ...start file... Breakpoint 1 at 0x........: file clean_after_fork.c, line 9. Breakpoint 2 at 0x........: file clean_after_fork.c, line 18. Breakpoint 3 at 0x........: file clean_after_fork.c, line 20. diff --git a/gdbserver_tests/mcinfcallRU.stderr.exp b/gdbserver_tests/mcinfcallRU.stderr.exp index c1dd15b00d..502dd8a37c 100644 --- a/gdbserver_tests/mcinfcallRU.stderr.exp +++ b/gdbserver_tests/mcinfcallRU.stderr.exp @@ -1,7 +1,4 @@ -loops/sleep_ms/burn/threads_spec: 1 0 2000000000 B-B-B-B- -Brussels ready to sleep and/or burn -London ready to sleep and/or burn -Petaouchnok ready to sleep and/or burn +loops/sleep_ms/burn/threads_spec: 1 0 2000000000 ------B- main ready to sleep and/or burn pid .... Thread .... inferior call pushed from gdb in mcinfcallRU.stdinB.gdb Reset valgrind output to log (orderly_finish) diff --git a/gdbserver_tests/mcinfcallRU.stdinB.gdb b/gdbserver_tests/mcinfcallRU.stdinB.gdb index 08a149b271..7ca7290a93 100644 --- a/gdbserver_tests/mcinfcallRU.stdinB.gdb +++ b/gdbserver_tests/mcinfcallRU.stdinB.gdb @@ -1,5 +1,6 @@ # connect gdb to Valgrind gdbserver: target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcinfcallRU +echo vgdb launched process attached\n monitor vg.set vgdb-error 999999 # # We will interrupt in a few seconds (be sure all tasks are in diff --git a/gdbserver_tests/mcinfcallRU.vgtest b/gdbserver_tests/mcinfcallRU.vgtest index 957458bcb7..d8f54d3e76 100644 --- a/gdbserver_tests/mcinfcallRU.vgtest +++ b/gdbserver_tests/mcinfcallRU.vgtest @@ -1,6 +1,8 @@ # test inferior calls when all threads are in Runnable or Yielding mode prog: sleepers -args: 1 0 2000000000 B-B-B-B- +# We would like to use B-B-B-B- instead of ------B- but this gives +# too much dependencies to the scheduler fairness. +args: 1 0 2000000000 ------B- vgopts: --tool=memcheck --vgdb=yes --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-mcinfcallRU # filter_gdb to replace pid and Thread numbers. # Well, the test will verify we have 4 calls (for each thread) diff --git a/gdbserver_tests/mcinfcallWSRU.stderr.exp b/gdbserver_tests/mcinfcallWSRU.stderr.exp index 227f862dad..a6ac61769a 100644 --- a/gdbserver_tests/mcinfcallWSRU.stderr.exp +++ b/gdbserver_tests/mcinfcallWSRU.stderr.exp @@ -1,8 +1,7 @@ -loops/sleep_ms/burn/threads_spec: 100 100000000 1000000000 -S-SB-B- +loops/sleep_ms/burn/threads_spec: 100 100000000 1000000000 -S-S-SB- Brussels ready to sleep and/or burn London ready to sleep and/or burn Petaouchnok ready to sleep and/or burn main ready to sleep and/or burn pid .... Thread .... thread 1 inferior call pushed from gdb in mcinfcallWSRU.stdinB.gdb -pid .... Thread .... thread 4 inferior call pushed from gdb in mcinfcallWSRU.stdinB.gdb Reset valgrind output to log (orderly_finish) diff --git a/gdbserver_tests/mcinfcallWSRU.stderrB.exp b/gdbserver_tests/mcinfcallWSRU.stderrB.exp index 2e954dbdbf..860e07ef69 100644 --- a/gdbserver_tests/mcinfcallWSRU.stderrB.exp +++ b/gdbserver_tests/mcinfcallWSRU.stderrB.exp @@ -1,6 +1,4 @@ relaying data between gdb and process .... -Remote debugging using | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcinfcallWSRU -0x........ in _start () from ...start file... vgdb-error value changed from 0 to 999999 Breakpoint 1 at 0x........: file sleepers.c, line 72. Continuing. @@ -41,8 +39,13 @@ set pc, calling from gdb a function in the debugged process, ...) can only be accepted if the thread is VgTs_Runnable or VgTs_Yielding state Thread status is VgTs_WaitSys ' -[Switching to thread 4 (Thread ....)]#0 0x........ in do_burn () at sleepers.c:39 -39 for (i = 0; i < burn; i++) loopnr++; -$2 = void +[Switching to thread 4 (Thread ....)]#0 0x........ in syscall ... +Could not write register "xxx"; remote failure reply 'E. +ERROR changing register xxx regno y +gdb commands changing registers (pc, sp, ...) (e.g. 'jump', +set pc, calling from gdb a function in the debugged process, ...) +can only be accepted if the thread is VgTs_Runnable or VgTs_Yielding state +Thread status is VgTs_WaitSys +' monitor command request to kill this process Remote connection closed diff --git a/gdbserver_tests/mcinfcallWSRU.stdinB.gdb b/gdbserver_tests/mcinfcallWSRU.stdinB.gdb index 8429ddec60..4ccbcdccf4 100644 --- a/gdbserver_tests/mcinfcallWSRU.stdinB.gdb +++ b/gdbserver_tests/mcinfcallWSRU.stdinB.gdb @@ -1,5 +1,6 @@ # connect gdb to Valgrind gdbserver: target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcinfcallWSRU +echo vgdb launched process attached\n monitor vg.set vgdb-error 999999 # # ensure all threads are known diff --git a/gdbserver_tests/mcinfcallWSRU.vgtest b/gdbserver_tests/mcinfcallWSRU.vgtest index 859ba1782d..683be0229d 100644 --- a/gdbserver_tests/mcinfcallWSRU.vgtest +++ b/gdbserver_tests/mcinfcallWSRU.vgtest @@ -1,7 +1,9 @@ # test inferior calls when some threads are in Runnable or Yielding mode, # some threads are in WaitSys. prog: sleepers -args: 100 100000000 1000000000 -S-SB-B- +# We would like to have two threads running (i.e. -S-SB-B-) +# but this introduces too much dependencies to scheduler fairness. +args: 100 100000000 1000000000 -S-S-SB- vgopts: --tool=memcheck --vgdb=yes --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-mcinfcallWSRU # Disable on Darwin: inferior call rejected as it cannot find malloc. prereq: ../tests/os_test linux diff --git a/gdbserver_tests/mcleak.stdinB.gdb b/gdbserver_tests/mcleak.stdinB.gdb index 5cdcbe943f..15c533b4ae 100644 --- a/gdbserver_tests/mcleak.stdinB.gdb +++ b/gdbserver_tests/mcleak.stdinB.gdb @@ -1,5 +1,6 @@ # connect gdb to Valgrind gdbserver: target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcleak +echo vgdb launched process attached\n monitor vg.set vgdb-error 999999 # # diff --git a/gdbserver_tests/mcsignopass.stdinB.gdb b/gdbserver_tests/mcsignopass.stdinB.gdb index 44a5c08883..ef904d80ac 100644 --- a/gdbserver_tests/mcsignopass.stdinB.gdb +++ b/gdbserver_tests/mcsignopass.stdinB.gdb @@ -1,5 +1,6 @@ # connect gdb to Valgrind gdbserver: target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcsignopass +echo vgdb launched process attached\n monitor vg.set vgdb-error 999999 # # instruct gdb to not pass (i.e. ignore) these signals. diff --git a/gdbserver_tests/mcsignopass.stdoutB.exp b/gdbserver_tests/mcsignopass.stdoutB.exp index 70ff5ba1b3..06c00cab1a 100644 --- a/gdbserver_tests/mcsignopass.stdoutB.exp +++ b/gdbserver_tests/mcsignopass.stdoutB.exp @@ -1,5 +1,3 @@ -Remote debugging using | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcsignopass -0x........ in _start () from ...start file... Signal Stop Print Pass to program Description SIGSEGV Yes Yes No Segmentation fault Signal Stop Print Pass to program Description diff --git a/gdbserver_tests/mcsigpass.stdinB.gdb b/gdbserver_tests/mcsigpass.stdinB.gdb index ebd0cc759b..0e1799a5e0 100644 --- a/gdbserver_tests/mcsigpass.stdinB.gdb +++ b/gdbserver_tests/mcsigpass.stdinB.gdb @@ -1,5 +1,6 @@ # connect gdb to Valgrind gdbserver: target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcsigpass +echo vgdb launched process attached\n monitor vg.set vgdb-error 999999 # # After this continue, we will receive 5 signals. diff --git a/gdbserver_tests/mcsigpass.stdoutB.exp b/gdbserver_tests/mcsigpass.stdoutB.exp index e924592246..c7723dc325 100644 --- a/gdbserver_tests/mcsigpass.stdoutB.exp +++ b/gdbserver_tests/mcsigpass.stdoutB.exp @@ -1,5 +1,3 @@ -Remote debugging using | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcsigpass -0x........ in _start () from ...start file... Continuing. Program received signal SIGSEGV, Segmentation fault. 0x........ in test1 () at faultstatus.c:105 diff --git a/gdbserver_tests/mcvabits.stdinB.gdb b/gdbserver_tests/mcvabits.stdinB.gdb index 7aa423a70b..4fc1eeb3fb 100644 --- a/gdbserver_tests/mcvabits.stdinB.gdb +++ b/gdbserver_tests/mcvabits.stdinB.gdb @@ -1,5 +1,6 @@ # connect gdb to Valgrind gdbserver: target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcvabits +echo vgdb launched process attached\n monitor vg.set vgdb-error 999999 # # diff --git a/gdbserver_tests/mcvabits.stdoutB.exp b/gdbserver_tests/mcvabits.stdoutB.exp index 68df7e1426..e8d3661561 100644 --- a/gdbserver_tests/mcvabits.stdoutB.exp +++ b/gdbserver_tests/mcvabits.stdoutB.exp @@ -1,5 +1,3 @@ -Remote debugging using | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcvabits -0x........ in _start () from ...start file... Breakpoint 1 at 0x........: file t.c, line 100. Continuing. Breakpoint 1, breakme (line=112) at t.c:100 diff --git a/gdbserver_tests/mcwatchpoints.stdinB.gdb b/gdbserver_tests/mcwatchpoints.stdinB.gdb index 5ec79fa4a1..243453bd43 100644 --- a/gdbserver_tests/mcwatchpoints.stdinB.gdb +++ b/gdbserver_tests/mcwatchpoints.stdinB.gdb @@ -1,5 +1,6 @@ # connect gdb to Valgrind gdbserver: target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcwatchpoints +echo vgdb launched process attached\n monitor vg.set vgdb-error 999999 # # diff --git a/gdbserver_tests/mcwatchpoints.stdoutB.exp b/gdbserver_tests/mcwatchpoints.stdoutB.exp index 7c6e09d6a5..0604aebcbc 100644 --- a/gdbserver_tests/mcwatchpoints.stdoutB.exp +++ b/gdbserver_tests/mcwatchpoints.stdoutB.exp @@ -1,5 +1,3 @@ -Remote debugging using | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcwatchpoints -0x........ in _start () from ...start file... Breakpoint 1 at 0x........: file watchpoints.c, line 7. Continuing. Breakpoint 1, breakme (line=19) at watchpoints.c:7 diff --git a/gdbserver_tests/mssnapshot.stdinB.gdb b/gdbserver_tests/mssnapshot.stdinB.gdb index 42b56fe75d..efe5a7ed78 100644 --- a/gdbserver_tests/mssnapshot.stdinB.gdb +++ b/gdbserver_tests/mssnapshot.stdinB.gdb @@ -1,5 +1,6 @@ # connect gdb to Valgrind gdbserver: target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mssnapshot +echo vgdb launched process attached\n monitor vg.set vgdb-error 999999 # # diff --git a/gdbserver_tests/mssnapshot.stdoutB.exp b/gdbserver_tests/mssnapshot.stdoutB.exp index 0166d554d7..a2a7c5531b 100644 --- a/gdbserver_tests/mssnapshot.stdoutB.exp +++ b/gdbserver_tests/mssnapshot.stdoutB.exp @@ -1,5 +1,3 @@ -Remote debugging using | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mssnapshot -0x........ in _start () from ...start file... Breakpoint 1 at 0x........: file t.c, line 105. Continuing. Breakpoint 1, main (argc=1, argv=0x........) at t.c:105 diff --git a/gdbserver_tests/nlcontrolc.stdinB.gdb b/gdbserver_tests/nlcontrolc.stdinB.gdb index 53a8d68c4b..9fc513286f 100644 --- a/gdbserver_tests/nlcontrolc.stdinB.gdb +++ b/gdbserver_tests/nlcontrolc.stdinB.gdb @@ -1,5 +1,6 @@ # connect gdb to Valgrind gdbserver: target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-nlcontrolc +echo vgdb launched process attached\n monitor vg.set vgdb-error 999999 # # diff --git a/gdbserver_tests/nlcontrolc.stdoutB.exp b/gdbserver_tests/nlcontrolc.stdoutB.exp index a79f5d2c42..90d6d3c79b 100644 --- a/gdbserver_tests/nlcontrolc.stdoutB.exp +++ b/gdbserver_tests/nlcontrolc.stdoutB.exp @@ -1,5 +1,3 @@ -Remote debugging using | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-nlcontrolc -0x........ in _start () from ...start file... Continuing. Program received signal SIGTRAP, Trace/breakpoint trap. 0x........ in syscall ... diff --git a/gdbserver_tests/sleepers.c b/gdbserver_tests/sleepers.c index 67c3743724..13cc1e0d8b 100644 --- a/gdbserver_tests/sleepers.c +++ b/gdbserver_tests/sleepers.c @@ -155,23 +155,32 @@ int main (int argc, char *argv[]) b.name = "Brussels"; b.burn = *threads_spec++ == 'B'; b.sleep = *threads_spec++ == 'S'; - b.t = 1; - pthread_create(&ebbr, NULL, sleeper_or_burner, &b); - wait_ready(); + b.t = -1; + if (b.burn || b.sleep) { + b.t = 1; + pthread_create(&ebbr, NULL, sleeper_or_burner, &b); + wait_ready(); + } l.name = "London"; l.burn = *threads_spec++ == 'B'; l.sleep = *threads_spec++ == 'S'; - l.t = 2; - pthread_create(&egll, NULL, sleeper_or_burner, &l); - wait_ready(); + l.t = -1; + if (l.burn || l.sleep) { + l.t = 2; + pthread_create(&egll, NULL, sleeper_or_burner, &l); + wait_ready(); + } p.name = "Petaouchnok"; p.burn = *threads_spec++ == 'B'; p.sleep = *threads_spec++ == 'S'; - p.t = 3; - pthread_create(&zzzz, NULL, sleeper_or_burner, &p); - wait_ready(); + p.t = -1; + if (p.burn || p.sleep) { + p.t = 3; + pthread_create(&zzzz, NULL, sleeper_or_burner, &p); + wait_ready(); + } m.name = "main"; m.burn = *threads_spec++ == 'B'; @@ -179,9 +188,9 @@ int main (int argc, char *argv[]) m.t = 0; sleeper_or_burner(&m); - pthread_join(ebbr, NULL); - pthread_join(egll, NULL); - pthread_join(zzzz, NULL); + if (b.t != -1) pthread_join(ebbr, NULL); + if (l.t != -1) pthread_join(egll, NULL); + if (p.t != -1) pthread_join(zzzz, NULL); return 0; } diff --git a/tests/vg_regtest.in b/tests/vg_regtest.in index 68e31388a2..6712a0495b 100755 --- a/tests/vg_regtest.in +++ b/tests/vg_regtest.in @@ -37,6 +37,8 @@ # --valgrind-lib: valgrind libraries to use. Default is $tests_dir/.in_place. # (This option should probably only be used in conjunction with # --valgrind.) +# --keep-unfiltered: keep a copy of the unfiltered output/error output +# of each test by adding an extension .unfiltered.out # # The easiest way is to run all tests in valgrind/ with (assuming you installed # in $PREFIX): @@ -113,10 +115,10 @@ use strict; # Global vars #---------------------------------------------------------------------------- my $usage="\n" - . "Usage:\n" - . " vg_regtest [--all, --valgrind, --valgrind-lib]\n" - . " Use EXTRA_REGTEST_OPTS to supply extra args for all tests\n" - . "\n"; + . "Usage:\n" + . " vg_regtest [--all, --valgrind, --valgrind-lib, --keep-unfiltered]\n" + . " Use EXTRA_REGTEST_OPTS to supply extra args for all tests\n" + . "\n"; my $tmp="vg_regtest.tmp.$$"; @@ -148,6 +150,7 @@ my $valgrind = "./coregrind/valgrind"; chomp(my $tests_dir = `pwd`); my $valgrind_lib = "$tests_dir/.in_place"; +my $keepunfiltered = 0; # default filter is the one named "filter_stderr" in the test's directory my $default_stderr_filter = "filter_stderr"; @@ -196,6 +199,8 @@ sub process_command_line() $valgrind = $1; } elsif ($arg =~ /^--valgrind-lib=(.*)$/) { $valgrind_lib = $1; + } elsif ($arg =~ /^--keep-unfiltered$/) { + $keepunfiltered = 1; } else { die $usage; } @@ -292,6 +297,17 @@ sub mysystem($) return $exit_code; } +# if $keepunfiltered, copies $1 to $1.unfiltered.out +# renames $0 tp $1 +sub filtered_rename($$) +{ + if ($keepunfiltered == 1) { + mysystem("cp $_[1] $_[1].unfiltered.out"); + } + rename ($_[0], $_[1]); +} + + # from a directory name like "/foo/cachesim/tests/" determine the tool name sub determine_tool() { @@ -402,7 +418,7 @@ sub do_one_test($$) # Filter stdout if (defined $stdout_filter) { mysystem("$stdout_filter < $name.stdout.out > $tmp"); - rename($tmp, "$name.stdout.out"); + filtered_rename($tmp, "$name.stdout.out"); } # Find all the .stdout.exp files. If none, use /dev/null. my @stdout_exps = <$name.stdout.exp*>; @@ -411,7 +427,7 @@ sub do_one_test($$) # Filter stderr mysystem("$stderr_filter < $name.stderr.out > $tmp"); - rename($tmp, "$name.stderr.out"); + filtered_rename($tmp, "$name.stderr.out"); # Find all the .stderr.exp files. At least one must exist. my @stderr_exps = <$name.stderr.exp*>; (0 != scalar @stderr_exps) or die "Could not find `$name.stderr.exp*'\n"; @@ -433,7 +449,7 @@ sub do_one_test($$) # Filter stdout if (defined $stdoutB_filter) { mysystem("$stdoutB_filter < $name.stdoutB.out > $tmp"); - rename($tmp, "$name.stdoutB.out"); + filtered_rename($tmp, "$name.stdoutB.out"); } # Find all the .stdoutB.exp files. If none, use /dev/null. my @stdoutB_exps = <$name.stdoutB.exp*>; @@ -442,7 +458,7 @@ sub do_one_test($$) # Filter stderr mysystem("$stderrB_filter < $name.stderrB.out > $tmp"); - rename($tmp, "$name.stderrB.out"); + filtered_rename($tmp, "$name.stderrB.out"); # Find all the .stderrB.exp files. At least one must exist. my @stderrB_exps = <$name.stderrB.exp*>; (0 != scalar @stderrB_exps) or die "Could not find `$name.stderrB.exp*'\n"; -- 2.47.2