diff --git a/gdb/testsuite/gdb.base/watchpoint-exec.c b/gdb/testsuite/gdb.base/watchpoint-exec.c
new file mode 100644
index 0000000000..56d3dbe69f
--- /dev/null
+++ b/gdb/testsuite/gdb.base/watchpoint-exec.c
@@ -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;
+}
diff --git a/gdb/testsuite/gdb.base/watchpoint-exec.exp b/gdb/testsuite/gdb.base/watchpoint-exec.exp
new file mode 100644
index 0000000000..d366add292
--- /dev/null
+++ b/gdb/testsuite/gdb.base/watchpoint-exec.exp
@@ -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"
diff --git a/gdb/x86-linux-nat.h b/gdb/x86-linux-nat.h
index 887e30eecd..9f024d4649 100644
--- a/gdb/x86-linux-nat.h
+++ b/gdb/x86-linux-nat.h
@@ -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); }
 
diff --git a/gdb/x86-nat.c b/gdb/x86-nat.c
index cd9ce17e8d..71f7c35ca9 100644
--- a/gdb/x86-nat.c
+++ b/gdb/x86-nat.c
@@ -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
diff --git a/gdb/x86-nat.h b/gdb/x86-nat.h
index baa4218a87..08df339a33 100644
--- a/gdb/x86-nat.h
+++ b/gdb/x86-nat.h
@@ -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);
 
