diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index eff940d..1869857 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -1738,19 +1738,6 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
   return 0;
 }
 
-/* Return true if the event in LP may be caused by breakpoint.  */
-
-static int
-wstatus_maybe_breakpoint (int wstatus)
-{
-  return (WIFSTOPPED (wstatus)
-	  && (WSTOPSIG (wstatus) == SIGTRAP
-	      /* SIGILL and SIGSEGV are also treated as traps in case a
-		 breakpoint is inserted at the current PC.  */
-	      || WSTOPSIG (wstatus) == SIGILL
-	      || WSTOPSIG (wstatus) == SIGSEGV));
-}
-
 /* Fetch the possibly triggered data watchpoint info and store it in
    CHILD.
 
@@ -1898,7 +1885,7 @@ linux_low_filter_event (int lwpid, int wstat)
   if (WIFSTOPPED (wstat) && WSTOPSIG (wstat) == SIGTRAP
       && check_stopped_by_watchpoint (child))
     ;
-  else if (WIFSTOPPED (wstat) && wstatus_maybe_breakpoint (wstat))
+  else if (WIFSTOPPED (wstat) && linux_wstatus_maybe_breakpoint (wstat))
     {
       if (check_stopped_by_breakpoint (child))
 	have_stop_pc = 1;
@@ -2739,7 +2726,8 @@ linux_wait_1 (ptid_t ptid,
      any that GDB specifically requested we ignore.  But never ignore
      SIGSTOP if we sent it ourselves, and do not ignore signals when
      stepping - they may require special handling to skip the signal
-     handler.  */
+     handler. Also never ignore signals that could be caused by a
+     breakpoint.  */
   /* FIXME drow/2002-06-09: Get signal numbers from the inferior's
      thread library?  */
   if (WIFSTOPPED (w)
@@ -2753,7 +2741,8 @@ linux_wait_1 (ptid_t ptid,
 #endif
 	  (pass_signals[gdb_signal_from_host (WSTOPSIG (w))]
 	   && !(WSTOPSIG (w) == SIGSTOP
-		&& current_thread->last_resume_kind == resume_stop))))
+		&& current_thread->last_resume_kind == resume_stop)
+	   && !linux_wstatus_maybe_breakpoint (w))))
     {
       siginfo_t info, *info_p;
 
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 169188a..ed007bd 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -3070,9 +3070,11 @@ linux_nat_filter_event (int lwpid, int status)
 	}
 
       /* When using hardware single-step, we need to report every signal.
-	 Otherwise, signals in pass_mask may be short-circuited.  */
+	 Otherwise, signals in pass_mask may be short-circuited
+	 except signals that might be caused by a breakpoint.  */
       if (!lp->step
-	  && WSTOPSIG (status) && sigismember (&pass_mask, WSTOPSIG (status)))
+	  && WSTOPSIG (status) && sigismember (&pass_mask, WSTOPSIG (status))
+	  && !linux_wstatus_maybe_breakpoint (status))
 	{
 	  linux_resume_one_lwp (lp, lp->step, signo);
 	  if (debug_linux_nat)
diff --git a/gdb/nat/linux-ptrace.c b/gdb/nat/linux-ptrace.c
index 0ce258f..1c67819 100644
--- a/gdb/nat/linux-ptrace.c
+++ b/gdb/nat/linux-ptrace.c
@@ -621,3 +621,16 @@ linux_is_extended_waitstatus (int wstat)
 {
   return (linux_ptrace_get_extended_event (wstat) != 0);
 }
+
+/* Return true if the event in LP may be caused by breakpoint.  */
+
+int
+linux_wstatus_maybe_breakpoint (int wstat)
+{
+  return (WIFSTOPPED (wstat)
+	  && (WSTOPSIG (wstat) == SIGTRAP
+	      /* SIGILL and SIGSEGV are also treated as traps in case a
+		 breakpoint is inserted at the current PC.  */
+	      || WSTOPSIG (wstat) == SIGILL
+	      || WSTOPSIG (wstat) == SIGSEGV));
+}
diff --git a/gdb/nat/linux-ptrace.h b/gdb/nat/linux-ptrace.h
index 137b61a..c5b0f14 100644
--- a/gdb/nat/linux-ptrace.h
+++ b/gdb/nat/linux-ptrace.h
@@ -107,5 +107,6 @@ extern int linux_supports_tracesysgood (void);
 extern void linux_ptrace_set_additional_flags (int);
 extern int linux_ptrace_get_extended_event (int wstat);
 extern int linux_is_extended_waitstatus (int wstat);
+extern int linux_wstatus_maybe_breakpoint (int wstat);
 
 #endif /* COMMON_LINUX_PTRACE_H */
diff --git a/gdb/testsuite/gdb.base/catch-gdb-caused-signals.c b/gdb/testsuite/gdb.base/catch-gdb-caused-signals.c
new file mode 100644
index 0000000..769858c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/catch-gdb-caused-signals.c
@@ -0,0 +1,36 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2015 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 is intended to be a simple dummy program for gdb to read.  */
+
+#include <unistd.h>
+#include <stdio.h>
+
+int
+main (void)
+{
+  int i = 0;
+
+  i++; /* set dprintf here */
+  return 0; /* set breakpoint here */
+}
+
+int
+return_one (void)
+{
+  return 1;
+}
diff --git a/gdb/testsuite/gdb.base/catch-gdb-caused-signals.exp b/gdb/testsuite/gdb.base/catch-gdb-caused-signals.exp
new file mode 100644
index 0000000..8ba3be5
--- /dev/null
+++ b/gdb/testsuite/gdb.base/catch-gdb-caused-signals.exp
@@ -0,0 +1,63 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2015 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/>.
+
+# Test that checks if we handle a SIGSEGV,SIGILL caused by gdb in the inferior
+# even if we have noprint,nostop options set in handle SIGSEV,SIGILL
+# See PR breakpoints/16812
+
+standard_testfile
+
+# Some targets can't call functions, so don't even bother with this
+# test.
+if [target_info exists gdb,cannot_call_functions] {
+    unsupported "cannot call functions"
+    return
+}
+
+set dp_location [gdb_get_line_number "set dprintf here"]
+set bp_location [gdb_get_line_number "set breakpoint here"]
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile debug]} {
+    return -1
+}
+
+if ![runto_main] {
+    fail "Can't run to main to make the tests"
+    return -1
+}
+
+gdb_test "handle SIGSEGV nostop noprint" \
+    "Signal\[ \t\]+Stop\[ \t\]+Print\[ \t\]+Pass to program\[ \t\]+Description\r\nSIGSEGV\[ \t\]+No\[ \t\]+No\[ \t\]+Yes\[ \t\].*"
+gdb_test "handle SIGILL nostop noprint" \
+    "Signal\[ \t\]+Stop\[ \t\]+Print\[ \t\]+Pass to program\[ \t\]+Description\r\nSIGILL\[ \t\]+No\[ \t\]+No\[ \t\]+Yes\[ \t\].*"
+
+gdb_test "print return_one()" " = 1"
+
+if ![target_info exists gdb,noinferiorio] {
+
+    # Clean up the breakpoint state.
+    delete_breakpoints
+
+    gdb_breakpoint $bp_location
+
+    gdb_test_no_output "set dprintf-style call"
+
+    # Also test with dprintf since the original bug was noticed using dprintf.
+    gdb_test "dprintf $dp_location,\"testdprintf\\n\"" "Dprintf .*"
+
+    gdb_test "continue" "testdprintf.*"
+}
