new file mode 100644
@@ -0,0 +1,48 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* This program exits if its first argument is --stop, otherwise it
+ tries to exec the first argument, passing --stop. In both cases it
+ writes to a global variable, which GDB will watch in this test. It
+ is meant to be called with its own pathname, so that it writes to
+ the variable, execs itself once, writes to the variable again, and
+ exits. */
+
+#include <unistd.h>
+#include <string.h>
+
+int watched_var = 0;
+
+int main (int argc, char *argv[])
+{
+ char *new_argv[3] = {"", "--stop", NULL};
+
+ if (argc != 2)
+ return 1;
+
+ new_argv[0] = argv[0];
+
+ watched_var = 1;
+
+ if (strcmp (argv[1], "--stop") == 0)
+ return 0;
+
+ if (execvp (argv[1], &new_argv[0]) < 0)
+ return 1;
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,53 @@
+# Copyright (C) 2019 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite.
+
+# Test if a hardware watchpoint triggers before and after a program
+# self-execs. This should happen since the watched global symbol must
+# be valid after the exec.
+
+if {[skip_hw_watchpoint_tests]} {
+ return
+}
+
+# The testsuite doesn't currently allow sending args to the stub.
+if [use_gdb_stub] {
+ unsupported "using gdb stub"
+ return
+}
+
+standard_testfile
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} {
+ return
+}
+
+gdb_test_no_output "set args $binfile" ""
+
+runto_main
+
+# We don't want to hit the breakpoint from runto_main after the exec.
+delete_breakpoints
+
+gdb_test "watch watched_var" "Hardware watchpoint.*: watched_var.*"
+
+set watchpoint_hit_re \
+ "Hardware watchpoint.*: watched_var.*Old value = 0.*New value = 1"
+
+gdb_test "continue" "$watchpoint_hit_re.*" "continue before exec"
+
+gdb_test "continue" "is executing new program.*$watchpoint_hit_re.*" \
+ "continue after exec"
@@ -65,6 +65,9 @@ struct x86_linux_nat_target : public x86_nat_target<linux_nat_target>
void low_forget_process (pid_t pid) override
{ x86_forget_process (pid); }
+ void low_post_exec (struct lwp_info *lwp) override
+ { x86_cleanup_dregs (lwp->ptid.pid ()); }
+
void low_prepare_to_resume (struct lwp_info *lwp) override
{ x86_linux_prepare_to_resume (lwp); }
@@ -133,13 +133,22 @@ x86_forget_process (pid_t pid)
}
/* Clear the reference counts and forget everything we knew about the
- debug registers. */
+ debug registers of process PID. */
void
-x86_cleanup_dregs (void)
+x86_cleanup_dregs (pid_t pid)
{
/* Starting from scratch has the same effect. */
- x86_forget_process (inferior_ptid.pid ());
+ x86_forget_process (pid);
+}
+
+/* Convenience overloaded function that calls x86_cleanup_dregs with
+ the pid of inferior_ptid. */
+
+void
+x86_cleanup_dregs (void)
+{
+ x86_cleanup_dregs (inferior_ptid.pid ());
}
/* Insert a watchpoint to watch a memory region which starts at
@@ -36,7 +36,13 @@
extern void x86_set_debug_register_length (int len);
-/* Use this function to reset the x86-nat.c debug register state. */
+/* Use this function to reset the x86-nat.c debug register state for
+ PID. */
+
+extern void x86_cleanup_dregs (pid_t pid);
+
+/* Use this function to reset the x86-nat.c debug register state for
+ the pid of inferior_ptid. */
extern void x86_cleanup_dregs (void);