diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 583f46d852..2aa3500a6c 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -246,6 +246,9 @@ struct breakpoint_ops bkpt_breakpoint_ops;
 /* Breakpoints set on probes.  */
 static struct breakpoint_ops bkpt_probe_breakpoint_ops;
 
+/* Tracepoints set on probes.  */
+static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
+
 /* Dynamic printf class type.  */
 struct breakpoint_ops dprintf_breakpoint_ops;
 
@@ -9163,6 +9166,41 @@ decode_static_tracepoint_spec (const char **arg_p)
   return sals;
 }
 
+/* Returns the breakpoint ops appropriate for use with with LOCATION_TYPE and
+   according to IS_TRACEPOINT.  */
+
+static const struct breakpoint_ops *
+breakpoint_ops_for_event_location_type (enum event_location_type location_type,
+					bool is_tracepoint)
+{
+  if (is_tracepoint)
+    {
+      if (location_type == PROBE_LOCATION)
+	return &tracepoint_probe_breakpoint_ops;
+      else
+	return &tracepoint_breakpoint_ops;
+    }
+  else
+    {
+      if (location_type == PROBE_LOCATION)
+	return &bkpt_probe_breakpoint_ops;
+      else
+	return &bkpt_breakpoint_ops;
+    }
+}
+
+/* See breakpoint.h.  */
+
+const struct breakpoint_ops *
+breakpoint_ops_for_event_location (const struct event_location *location,
+				   bool is_tracepoint)
+{
+  if (location)
+    return breakpoint_ops_for_event_location_type
+      (event_location_type (location), is_tracepoint);
+  return is_tracepoint ? &tracepoint_breakpoint_ops : &bkpt_breakpoint_ops;
+}
+
 /* See breakpoint.h.  */
 
 int
@@ -9344,16 +9382,10 @@ break_command_1 (const char *arg, int flag, int from_tty)
   enum bptype type_wanted = (flag & BP_HARDWAREFLAG
 			     ? bp_hardware_breakpoint
 			     : bp_breakpoint);
-  struct breakpoint_ops *ops;
 
   event_location_up location = string_to_event_location (&arg, current_language);
-
-  /* Matching breakpoints on probes.  */
-  if (location != NULL
-      && event_location_type (location.get ()) == PROBE_LOCATION)
-    ops = &bkpt_probe_breakpoint_ops;
-  else
-    ops = &bkpt_breakpoint_ops;
+  const struct breakpoint_ops *ops = breakpoint_ops_for_event_location
+    (location.get (), false /* is_tracepoint */);
 
   create_breakpoint (get_current_arch (),
 		     location.get (),
@@ -12802,8 +12834,7 @@ tracepoint_decode_location (struct breakpoint *b,
 
 struct breakpoint_ops tracepoint_breakpoint_ops;
 
-/* The breakpoint_ops structure to be use on tracepoints placed in a
-   static probe.  */
+/* Virtual table for tracepoints on static probes.  */
 
 static void
 tracepoint_probe_create_sals_from_location
@@ -12824,8 +12855,6 @@ tracepoint_probe_decode_location (struct breakpoint *b,
   return bkpt_probe_decode_location (b, location, search_pspace);
 }
 
-static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
-
 /* Dprintf breakpoint_ops methods.  */
 
 static void
@@ -14467,15 +14496,10 @@ set_tracepoint_count (int num)
 static void
 trace_command (const char *arg, int from_tty)
 {
-  struct breakpoint_ops *ops;
-
   event_location_up location = string_to_event_location (&arg,
 							 current_language);
-  if (location != NULL
-      && event_location_type (location.get ()) == PROBE_LOCATION)
-    ops = &tracepoint_probe_breakpoint_ops;
-  else
-    ops = &tracepoint_breakpoint_ops;
+  const struct breakpoint_ops *ops = breakpoint_ops_for_event_location
+    (location.get (), true /* is_tracepoint */);
 
   create_breakpoint (get_current_arch (),
 		     location.get (),
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index a9d689d02a..071ae79d68 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -1352,6 +1352,15 @@ extern void init_catchpoint (struct breakpoint *b,
 extern void install_breakpoint (int internal, std::unique_ptr<breakpoint> &&b,
 				int update_gll);
 
+/* Returns the breakpoint ops appropriate for use with with LOCATION and
+   according to IS_TRACEPOINT.  Use this to ensure, for example, that you pass
+   the correct ops to create_breakpoint for probe locations.  If LOCATION is
+   null, returns bkpt_breakpoint_ops (or tracepoint_breakpoint_ops, if
+   IS_TRACEPOINT is non-zero).  */
+
+extern const struct breakpoint_ops *breakpoint_ops_for_event_location
+  (const struct event_location *location, bool is_tracepoint);
+
 /* Flags that can be passed down to create_breakpoint, etc., to affect
    breakpoint creation in several ways.  */
 
diff --git a/gdb/guile/scm-breakpoint.c b/gdb/guile/scm-breakpoint.c
index a75daa0001..a6404d544b 100644
--- a/gdb/guile/scm-breakpoint.c
+++ b/gdb/guile/scm-breakpoint.c
@@ -437,13 +437,15 @@ gdbscm_register_breakpoint_x (SCM self)
 	{
 	case bp_breakpoint:
 	  {
+	    const breakpoint_ops *ops =
+	      breakpoint_ops_for_event_location (eloc.get (), false);
 	    create_breakpoint (get_current_arch (),
 			       eloc.get (), NULL, -1, NULL,
 			       0,
 			       0, bp_breakpoint,
 			       0,
 			       AUTO_BOOLEAN_TRUE,
-			       &bkpt_breakpoint_ops,
+			       ops,
 			       0, 1, internal, 0);
 	    break;
 	  }
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 4170737416..32494aec72 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -828,13 +828,16 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
 		location = new_explicit_location (&explicit_loc);
 	      }
 
+	    const struct breakpoint_ops *ops =
+	      breakpoint_ops_for_event_location (location.get (), false);
+
 	    create_breakpoint (python_gdbarch,
 			       location.get (), NULL, -1, NULL,
 			       0,
 			       temporary_bp, bp_breakpoint,
 			       0,
 			       AUTO_BOOLEAN_TRUE,
-			       &bkpt_breakpoint_ops,
+			       ops,
 			       0, 1, internal_bp, 0);
 	    break;
 	  }
diff --git a/gdb/testsuite/gdb.guile/scm-breakpoint.c b/gdb/testsuite/gdb.guile/scm-breakpoint.c
index 1670041677..ed7dbdba91 100644
--- a/gdb/testsuite/gdb.guile/scm-breakpoint.c
+++ b/gdb/testsuite/gdb.guile/scm-breakpoint.c
@@ -15,6 +15,10 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see  <http://www.gnu.org/licenses/>.  */
 
+#ifdef USE_PROBES
+#include <sys/sdt.h>
+#endif
+
 int result = 0;
 
 int multiply (int i)
@@ -38,6 +42,9 @@ int main (int argc, char *argv[])
     {
       result += multiply (foo);  /* Break at multiply. */
       result += add (bar); /* Break at add. */
+#ifdef USE_PROBES
+      DTRACE_PROBE1 (test, result_updated, result);
+#endif
     }
 
   return 0; /* Break at end. */
diff --git a/gdb/testsuite/gdb.guile/scm-breakpoint.exp b/gdb/testsuite/gdb.guile/scm-breakpoint.exp
index 47bc80c2c8..183ad1671f 100644
--- a/gdb/testsuite/gdb.guile/scm-breakpoint.exp
+++ b/gdb/testsuite/gdb.guile/scm-breakpoint.exp
@@ -499,6 +499,28 @@ proc test_bkpt_address {} {
 	".*Breakpoint ($decimal)+ at .*$srcfile, line ($decimal)+\."
 }
 
+proc test_bkpt_probe {} {
+    global decimal hex testfile srcfile
+
+    if { [prepare_for_testing "failed to prepare" ${testfile}-probes \
+	    ${srcfile} {additional_flags=-DUSE_PROBES}] } {
+	return -1
+    }
+
+    if ![gdb_guile_runto_main] then {
+	return
+    }
+
+    gdb_scm_test_silent_cmd \
+	"guile (define bp1 (make-breakpoint \"-probe test:result_updated\"))" \
+	"create probe breakpoint"
+
+    gdb_test \
+	"guile (register-breakpoint! bp1)" \
+	"Breakpoint $decimal at $hex" \
+	"register probe breakpoint"
+}
+
 test_bkpt_basic
 test_bkpt_deletion
 test_bkpt_cond_and_cmds
@@ -508,3 +530,4 @@ test_bkpt_internal
 test_bkpt_eval_funcs
 test_bkpt_registration
 test_bkpt_address
+test_bkpt_probe
diff --git a/gdb/testsuite/gdb.python/py-breakpoint.c b/gdb/testsuite/gdb.python/py-breakpoint.c
index d102a5f306..12adc99a1b 100644
--- a/gdb/testsuite/gdb.python/py-breakpoint.c
+++ b/gdb/testsuite/gdb.python/py-breakpoint.c
@@ -15,6 +15,10 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see  <http://www.gnu.org/licenses/>.  */
 
+#ifdef USE_PROBES
+#include <sys/sdt.h>
+#endif
+
 int result = 0;
 
 namespace foo_ns
@@ -46,6 +50,9 @@ int main (int argc, char *argv[])
     {
       result += multiply (foo);  /* Break at multiply. */
       result += add (bar); /* Break at add. */
+#ifdef USE_PROBES
+      DTRACE_PROBE1 (test, result_updated, result);
+#endif
     }
 
   return 0; /* Break at end. */
diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp
index 625977c0ad..95f2b2905d 100644
--- a/gdb/testsuite/gdb.python/py-breakpoint.exp
+++ b/gdb/testsuite/gdb.python/py-breakpoint.exp
@@ -695,6 +695,25 @@ proc_with_prefix test_bkpt_qualified {} {
 	"-q in spec string and qualified false"
 }
 
+proc_with_prefix test_bkpt_probe {} {
+    global decimal hex testfile srcfile
+
+    if { [prepare_for_testing "failed to prepare" ${testfile}-probes \
+	    ${srcfile} {debug c++ additional_flags=-DUSE_PROBES}] } {
+	return -1
+    }
+
+    if ![runto_main] then {
+	fail "cannot run to main."
+	return 0
+    }
+
+    gdb_test \
+	"python gdb.Breakpoint(\"-probe test:result_updated\")" \
+	"Breakpoint $decimal at $hex" \
+	"-probe in spec string"
+}
+
 test_bkpt_basic
 test_bkpt_deletion
 test_bkpt_cond_and_cmds
@@ -708,3 +727,4 @@ test_bkpt_pending
 test_bkpt_events
 test_bkpt_explicit_loc
 test_bkpt_qualified
+test_bkpt_probe
