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 <linux/ptrace.h> 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 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_gdbserver/valgrind-low.c b/coregrind/m_gdbserver/valgrind-low.c
index fc376fa..5d3f708 100644
--- a/coregrind/m_gdbserver/valgrind-low.c
+++ b/coregrind/m_gdbserver/valgrind-low.c
@@ -176,7 +176,7 @@
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 @@
}
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 fffc7cc..d5cacd3 100644
--- a/coregrind/vgdb.c
+++ b/coregrind/vgdb.c
@@ -51,6 +51,7 @@
# if defined(VGO_linux)
#include <sys/prctl.h>
+#include <linux/ptrace.h>
# endif
/* vgdb has two usages:
@@ -624,67 +625,137 @@
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 @@
}
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 @@
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 @@
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 9dd7a3b..9069470 100755
--- a/gdbserver_tests/filter_gdb
+++ b/gdbserver_tests/filter_gdb
@@ -14,6 +14,10 @@
# 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 @@
# 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 @@
# 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 @@
-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 @@
-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 71b3511..2edc75a 100755
--- a/gdbserver_tests/filter_vgdb
+++ b/gdbserver_tests/filter_vgdb
@@ -7,9 +7,11 @@
# 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 a154925..19f3d86 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 2c51b39..e12d2e4 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 b79f41a..41ea5e3 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 145ad93..f91ca9e 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 8c6a8d3..6db3d3a 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 c1dd15b..502dd8a 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 08a149b..7ca7290 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 957458b..d8f54d3 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 227f862..a6ac617 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 2e954db..860e07e 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 @@
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 8429dde..4ccbcdc 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 859ba17..683be02 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 5cdcbe9..15c533b 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 44a5c08..ef904d8 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 70ff5ba..06c00ca 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 ebd0cc7..0e1799a 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 e924592..c7723dc 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 7aa423a..4fc1eeb 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 68df7e1..e8d3661 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 5ec79fa..243453b 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 7c6e09d..0604aeb 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 42b56fe..efe5a7e 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 0166d55..a2a7c55 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 53a8d68..9fc5132 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 a79f5d2..90d6d3c 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 67c3743..13cc1e0 100644
--- a/gdbserver_tests/sleepers.c
+++ b/gdbserver_tests/sleepers.c
@@ -155,23 +155,32 @@
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 @@
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 68e3138..6712a04 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 @@
# 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 @@
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 @@
$valgrind = $1;
} elsif ($arg =~ /^--valgrind-lib=(.*)$/) {
$valgrind_lib = $1;
+ } elsif ($arg =~ /^--keep-unfiltered$/) {
+ $keepunfiltered = 1;
} else {
die $usage;
}
@@ -292,6 +297,17 @@
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 @@
# 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 @@
# 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 @@
# 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 @@
# 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";