diff --git a/gdb/NEWS b/gdb/NEWS
index 6f27f7b20c2..436a1dfcc33 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -13,6 +13,13 @@
   'thread' or 'task' keywords are parsed at the time the breakpoint is
   created, rather than at the time the breakpoint becomes non-pending.
 
+* Thread-specific breakpoints are only inserted into the program space
+  in which the thread of interest is running.  In most cases program
+  spaces are unique for each inferior, so this means that
+  thread-specific breakpoints will usually only be inserted for the
+  inferior containing the thread of interest.  The breakpoint will
+  be hit no less than before.
+
 * Changed commands
 
 disassemble
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 411062cad27..62db0f33823 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -12019,11 +12019,11 @@ struct ada_catchpoint : public code_breakpoint
     enable_state = enabled ? bp_enabled : bp_disabled;
     language = language_ada;
 
-    re_set ();
+    re_set (pspace);
   }
 
   struct bp_location *allocate_location () override;
-  void re_set () override;
+  void re_set (program_space *pspace) override;
   void check_status (struct bpstat *bs) override;
   enum print_stop_action print_it (const bpstat *bs) const override;
   bool print_one (const bp_location **) const override;
@@ -12068,7 +12068,7 @@ static struct symtab_and_line ada_exception_sal
    catchpoint kinds.  */
 
 void
-ada_catchpoint::re_set ()
+ada_catchpoint::re_set (program_space *pspace)
 {
   std::vector<symtab_and_line> sals;
   try
diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c
index 47d534c5ee8..e661d1624e8 100644
--- a/gdb/break-catch-throw.c
+++ b/gdb/break-catch-throw.c
@@ -82,10 +82,10 @@ struct exception_catchpoint : public code_breakpoint
 				     _("invalid type-matching regexp")))
   {
     pspace = current_program_space;
-    re_set ();
+    re_set (pspace);
   }
 
-  void re_set () override;
+  void re_set (program_space *pspace) override;
   enum print_stop_action print_it (const bpstat *bs) const override;
   bool print_one (const bp_location **) const override;
   void print_mention () const override;
@@ -198,7 +198,7 @@ exception_catchpoint::check_status (struct bpstat *bs)
 /* Implement the 're_set' method.  */
 
 void
-exception_catchpoint::re_set ()
+exception_catchpoint::re_set (program_space *pspace)
 {
   std::vector<symtab_and_line> sals;
   struct program_space *filter_pspace = current_program_space;
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index e9aa80e3c41..87987e4d6ac 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -91,9 +91,12 @@
 static void map_breakpoint_numbers (const char *,
 				    gdb::function_view<void (breakpoint *)>);
 
-static void
-  create_sals_from_location_spec_default (location_spec *locspec,
-					  linespec_result *canonical);
+static void parse_breakpoint_sals (location_spec *locspec,
+				   linespec_result *canonical,
+				   program_space *search_pspace);
+
+static void breakpoint_re_set_one (breakpoint *b,
+				   program_space *filter_pspace);
 
 static void create_breakpoints_sal (struct gdbarch *,
 				    struct linespec_result *,
@@ -283,11 +286,12 @@ static bool strace_marker_p (struct breakpoint *b);
 
 static void bkpt_probe_create_sals_from_location_spec
      (location_spec *locspec,
-      struct linespec_result *canonical);
+      struct linespec_result *canonical,
+      struct program_space *search_pspace);
 
 const struct breakpoint_ops code_breakpoint_ops =
 {
-  create_sals_from_location_spec_default,
+  parse_breakpoint_sals,
   create_breakpoints_sal,
 };
 
@@ -352,7 +356,7 @@ struct internal_breakpoint : public code_breakpoint
     disposition = disp_donttouch;
   }
 
-  void re_set () override;
+  void re_set (program_space *pspace) override;
   void check_status (struct bpstat *bs) override;
   enum print_stop_action print_it (const bpstat *bs) const override;
   void print_mention () const override;
@@ -389,7 +393,7 @@ struct momentary_breakpoint : public code_breakpoint
     gdb_assert (inferior == -1);
   }
 
-  void re_set () override;
+  void re_set (program_space *pspace) override;
   void check_status (struct bpstat *bs) override;
   enum print_stop_action print_it (const bpstat *bs) const override;
   void print_mention () const override;
@@ -400,7 +404,7 @@ struct dprintf_breakpoint : public ordinary_breakpoint
 {
   using ordinary_breakpoint::ordinary_breakpoint;
 
-  void re_set () override;
+  void re_set (program_space *pspace) override;
   int breakpoint_hit (const struct bp_location *bl,
 		      const address_space *aspace,
 		      CORE_ADDR bp_addr,
@@ -1549,7 +1553,36 @@ breakpoint_set_thread (struct breakpoint *b, int thread)
   int old_thread = b->thread;
   b->thread = thread;
   if (old_thread != thread)
-    notify_breakpoint_modified (b);
+    {
+      /* If THREAD is in a different program_space than OLD_THREAD, or the
+	 breakpoint has switched to or from being thread-specific, then we
+	 need to re-set the locations of this breakpoint.  First, figure
+	 out the program_space for the old and new threads, use a value of
+	 nullptr to indicate the breakpoint is in all program spaces.  */
+      program_space *old_pspace = nullptr;
+      if (old_thread != -1)
+	{
+	  struct thread_info *thr = find_thread_global_id (old_thread);
+	  gdb_assert (thr != nullptr);
+	  old_pspace = thr->inf->pspace;
+	}
+
+      program_space *new_pspace = nullptr;
+      if (thread != -1)
+	{
+	  struct thread_info *thr = find_thread_global_id (thread);
+	  gdb_assert (thr != nullptr);
+	  new_pspace = thr->inf->pspace;
+	}
+
+      /* If the program space has changed for this breakpoint, then
+	 re-evaluate it's locations.  */
+      if (old_pspace != new_pspace)
+	breakpoint_re_set_one (b, new_pspace);
+
+      /* Let others know the breakpoint has changed.  */
+      notify_breakpoint_modified (b);
+    }
 }
 
 /* See breakpoint.h.  */
@@ -1568,7 +1601,34 @@ breakpoint_set_inferior (struct breakpoint *b, int inferior)
   int old_inferior = b->inferior;
   b->inferior = inferior;
   if (old_inferior != inferior)
-    notify_breakpoint_modified (b);
+    {
+      /* If INFERIOR is in a different program_space than OLD_INFERIOR, or
+	 the breakpoint has switch to or from inferior-specific, then we
+	 need to re-set the locations of this breakpoint.  First, figure
+	 out the program_space for the old and new inferiors, use a value
+	 of nullptr to indicate the breakpoint is in all program
+	 spaces.  */
+      program_space *old_pspace = nullptr;
+      if (old_inferior != -1)
+	{
+	  struct inferior *inf = find_inferior_id (old_inferior);
+	  gdb_assert (inf != nullptr);
+	  old_pspace = inf->pspace;
+	}
+
+      program_space *new_pspace = nullptr;
+      if (inferior != -1)
+	{
+	  struct inferior *inf = find_inferior_id (inferior);
+	  gdb_assert (inf != nullptr);
+	  new_pspace = inf->pspace;
+	}
+
+      if (old_pspace != new_pspace)
+	breakpoint_re_set_one (b, new_pspace);
+
+      notify_breakpoint_modified (b);
+    }
 }
 
 /* See breakpoint.h.  */
@@ -8809,7 +8869,8 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
 
 static void
 parse_breakpoint_sals (location_spec *locspec,
-		       struct linespec_result *canonical)
+		       struct linespec_result *canonical,
+		       struct program_space *search_pspace)
 {
   struct symtab_and_line cursal;
 
@@ -8874,7 +8935,7 @@ parse_breakpoint_sals (location_spec *locspec,
 	      && strchr ("+-", spec[0]) != NULL
 	      && spec[1] != '['))
 	{
-	  decode_line_full (locspec, DECODE_LINE_FUNFIRSTLINE, NULL,
+	  decode_line_full (locspec, DECODE_LINE_FUNFIRSTLINE, search_pspace,
 			    get_last_displayed_symtab (),
 			    get_last_displayed_line (),
 			    canonical, NULL, NULL);
@@ -8882,7 +8943,7 @@ parse_breakpoint_sals (location_spec *locspec,
 	}
     }
 
-  decode_line_full (locspec, DECODE_LINE_FUNFIRSTLINE, NULL,
+  decode_line_full (locspec, DECODE_LINE_FUNFIRSTLINE, search_pspace,
 		    cursal.symtab, cursal.line, canonical, NULL, NULL);
 }
 
@@ -8981,6 +9042,39 @@ breakpoint_ops_for_location_spec_type (enum location_spec_type locspec_type,
     }
 }
 
+/* Return the program space to use as a filter when searching for locations
+   of a breakpoint specific to THREAD or INFERIOR.  If THREAD and INFERIOR
+   are both -1, meaning all threads/inferiors, then this function returns
+   nullptr, indicating no program space filtering should be performed.
+   Otherwise, this function returns the program space for the inferior that
+   contains THREAD (when THREAD is not -1), or the program space for
+   INFERIOR (when INFERIOR is not -1).  */
+
+static struct program_space *
+find_program_space_for_breakpoint (int thread, int inferior)
+{
+  if (thread != -1)
+    {
+      gdb_assert (inferior == -1);
+
+      struct thread_info *thr = find_thread_global_id (thread);
+      gdb_assert (thr != nullptr);
+      gdb_assert (thr->inf != nullptr);
+      return thr->inf->pspace;
+    }
+  else if (inferior != -1)
+    {
+      gdb_assert (thread == -1);
+
+      struct inferior *inf = find_inferior_id (inferior);
+      gdb_assert (inf != nullptr);
+
+      return inf->pspace;
+    }
+
+  return nullptr;
+}
+
 /* See breakpoint.h.  */
 
 const struct breakpoint_ops *
@@ -9082,7 +9176,10 @@ create_breakpoint (struct gdbarch *gdbarch,
 
   try
     {
-      ops->create_sals_from_location_spec (locspec, &canonical);
+      struct program_space *search_pspace
+	= find_program_space_for_breakpoint (thread, inferior);
+      ops->create_sals_from_location_spec (locspec, &canonical,
+					   search_pspace);
     }
   catch (const gdb_exception_error &e)
     {
@@ -9555,7 +9652,7 @@ break_range_command (const char *arg, int from_tty)
   arg_start = arg;
   location_spec_up start_locspec
     = string_to_location_spec (&arg, current_language);
-  parse_breakpoint_sals (start_locspec.get (), &canonical_start);
+  parse_breakpoint_sals (start_locspec.get (), &canonical_start, nullptr);
 
   if (arg[0] != ',')
     error (_("Too few arguments."));
@@ -9656,7 +9753,7 @@ watchpoint_exp_is_const (const struct expression *exp)
 /* Implement the "re_set" method for watchpoints.  */
 
 void
-watchpoint::re_set ()
+watchpoint::re_set (struct program_space *pspace)
 {
   /* Watchpoint can be either on expression using entirely global
      variables, or it can be on local variables.
@@ -11767,7 +11864,7 @@ breakpoint::print_recreate (struct ui_file *fp) const
 /* Default breakpoint_ops methods.  */
 
 void
-code_breakpoint::re_set ()
+code_breakpoint::re_set (struct program_space *pspace)
 {
   /* FIXME: is this still reachable?  */
   if (breakpoint_location_spec_empty_p (this))
@@ -11777,7 +11874,7 @@ code_breakpoint::re_set ()
       return;
     }
 
-  re_set_default ();
+  re_set_default (pspace);
 }
 
 int
@@ -11983,7 +12080,7 @@ code_breakpoint::decode_location_spec (location_spec *locspec,
 /* Virtual table for internal breakpoints.  */
 
 void
-internal_breakpoint::re_set ()
+internal_breakpoint::re_set (struct program_space *pspace)
 {
   switch (type)
     {
@@ -12076,7 +12173,7 @@ internal_breakpoint::print_mention () const
 /* Virtual table for momentary breakpoints  */
 
 void
-momentary_breakpoint::re_set ()
+momentary_breakpoint::re_set (struct program_space *pspace)
 {
   /* Keep temporary breakpoints, which can be encountered when we step
      over a dlopen call and solib_add is resetting the breakpoints.
@@ -12117,12 +12214,13 @@ longjmp_breakpoint::~longjmp_breakpoint ()
 
 static void
 bkpt_probe_create_sals_from_location_spec (location_spec *locspec,
-					   struct linespec_result *canonical)
+					   struct linespec_result *canonical,
+					   struct program_space *search_pspace)
 
 {
   struct linespec_sals lsal;
 
-  lsal.sals = parse_probes (locspec, NULL, canonical);
+  lsal.sals = parse_probes (locspec, search_pspace, canonical);
   lsal.canonical = xstrdup (canonical->locspec->to_string ());
   canonical->lsals.push_back (std::move (lsal));
 }
@@ -12212,9 +12310,9 @@ tracepoint::print_recreate (struct ui_file *fp) const
 }
 
 void
-dprintf_breakpoint::re_set ()
+dprintf_breakpoint::re_set (struct program_space *pspace)
 {
-  re_set_default ();
+  re_set_default (pspace);
 
   /* 1 - connect to target 1, that can run breakpoint commands.
      2 - create a dprintf, which resolves fine.
@@ -12268,8 +12366,10 @@ dprintf_breakpoint::after_condition_true (struct bpstat *bs)
    markers (`-m').  */
 
 static void
-strace_marker_create_sals_from_location_spec (location_spec *locspec,
-					      struct linespec_result *canonical)
+strace_marker_create_sals_from_location_spec
+	(location_spec *locspec,
+	 struct linespec_result *canonical,
+	 struct program_space *search_pspace)
 {
   struct linespec_sals lsal;
   const char *arg_start, *arg;
@@ -12784,12 +12884,32 @@ update_breakpoint_locations (code_breakpoint *b,
      all locations are in the same shared library, that was unloaded.
      We'd like to retain the location, so that when the library is
      loaded again, we don't loose the enabled/disabled status of the
-     individual locations.  */
+     individual locations.
+
+     Thread specific breakpoints will also trigger this case if the thread
+     is changed to a different program space, and all of the old locations
+     go out of scope.  In this case we do (currently) discard the old
+     locations -- we assume the change in thread is permanent and the old
+     locations will never come back into scope.  */
   if (all_locations_are_pending (b, filter_pspace) && sals.empty ())
-    return;
+    {
+      if (b->thread != -1)
+	b->clear_locations ();
+      return;
+    }
 
   bp_location_list existing_locations = b->steal_locations (filter_pspace);
 
+  /* If this is a thread-specific breakpoint then any locations left on the
+     breakpoint are for a program space in which the thread of interest
+     does not operate.  This can happen when the user changes the thread of
+     a thread-specific breakpoint.
+
+     We assume that the change in thread is permanent, and that the old
+     locations will never be used again, so discard them now.  */
+  if (b->thread != -1)
+    b->clear_locations ();
+
   for (const auto &sal : sals)
     {
       struct bp_location *new_loc;
@@ -12955,40 +13075,45 @@ code_breakpoint::location_spec_to_sals (location_spec *locspec,
    locations.  */
 
 void
-code_breakpoint::re_set_default ()
+code_breakpoint::re_set_default (struct program_space *filter_pspace)
 {
-  struct program_space *filter_pspace = current_program_space;
   std::vector<symtab_and_line> expanded, expanded_end;
 
-  int found;
-  std::vector<symtab_and_line> sals = location_spec_to_sals (locspec.get (),
-							     filter_pspace,
-							     &found);
-  if (found)
-    expanded = std::move (sals);
-
-  if (locspec_range_end != nullptr)
-    {
-      std::vector<symtab_and_line> sals_end
-	= location_spec_to_sals (locspec_range_end.get (),
-				 filter_pspace, &found);
+  /* If this breakpoint is thread-specific then find the program space in
+     which the specific thread exists.  Otherwise, for breakpoints that are
+     not thread-specific THREAD_PSPACE will be nullptr.  */
+  program_space *bp_pspace
+    = find_program_space_for_breakpoint (this->thread, this->inferior);
+
+  /* If this is not a thread or inferior specific breakpoint, or it is a
+     thread or inferior specific breakpoint but we are looking for new
+     locations in the program space that the specific thread or inferior is
+     running, then look for new locations for this breakpoint.  */
+  if (bp_pspace == nullptr || filter_pspace == bp_pspace)
+    {
+      int found;
+      std::vector<symtab_and_line> sals
+	= location_spec_to_sals (locspec.get (), filter_pspace, &found);
       if (found)
-	expanded_end = std::move (sals_end);
+	expanded = std::move (sals);
+
+      if (locspec_range_end != nullptr)
+	{
+	  std::vector<symtab_and_line> sals_end
+	    = location_spec_to_sals (locspec_range_end.get (),
+				     filter_pspace, &found);
+	  if (found)
+	    expanded_end = std::move (sals_end);
+	}
     }
 
+  /* Update the locations for this breakpoint.  For thread-specific
+     breakpoints this will remove any old locations that are for the wrong
+     program space -- this can happen if the user changes the thread of a
+     thread-specific breakpoint.  */
   update_breakpoint_locations (this, filter_pspace, expanded, expanded_end);
 }
 
-/* Default method for creating SALs from an address string.  It basically
-   calls parse_breakpoint_sals.  Return 1 for success, zero for failure.  */
-
-static void
-create_sals_from_location_spec_default (location_spec *locspec,
-					struct linespec_result *canonical)
-{
-  parse_breakpoint_sals (locspec, canonical);
-}
-
 /* Re-set breakpoint locations for the current program space.
    Locations bound to other program spaces are left untouched.  */
 
@@ -13023,7 +13148,7 @@ breakpoint_re_set (void)
 	  {
 	    input_radix = b.input_radix;
 	    set_language (b.language);
-	    b.re_set ();
+	    b.re_set (current_program_space);
 	  }
 	catch (const gdb_exception &ex)
 	  {
@@ -13044,6 +13169,53 @@ breakpoint_re_set (void)
   /* Now we can insert.  */
   update_global_location_list (UGLL_MAY_INSERT);
 }
+
+/* Re-set locations for breakpoint B in FILTER_PSPACE.  If FILTER_PSPACE is
+   nullptr then re-set locations for B in all program spaces.  Locations
+   bound to program spaces other than FILTER_PSPACE are left untouched.  */
+
+static void
+breakpoint_re_set_one (breakpoint *b, program_space *filter_pspace)
+{
+  {
+    scoped_restore_current_language save_language;
+    scoped_restore save_input_radix = make_scoped_restore (&input_radix);
+    scoped_restore_current_pspace_and_thread restore_pspace_thread;
+
+    /* To ::re_set each breakpoint we set the current_language to the
+       language of the breakpoint before re-evaluating the breakpoint's
+       location.  This change can unfortunately get undone by accident if
+       the language_mode is set to auto, and we either switch frames, or
+       more likely in this context, we select the current frame.
+
+       We prevent this by temporarily turning the language_mode to
+       language_mode_manual.  We restore it once all breakpoints
+       have been reset.  */
+    scoped_restore save_language_mode = make_scoped_restore (&language_mode);
+    language_mode = language_mode_manual;
+
+    /* Note: we must not try to insert locations until after all
+       breakpoints have been re-set.  Otherwise, e.g., when re-setting
+       breakpoint 1, we'd insert the locations of breakpoint 2, which
+       hadn't been re-set yet, and thus may have stale locations.  */
+
+    try
+      {
+	input_radix = b->input_radix;
+	set_language (b->language);
+	b->re_set (filter_pspace);
+      }
+    catch (const gdb_exception &ex)
+      {
+	exception_fprintf (gdb_stderr, ex,
+			   "Error in re-setting breakpoint %d: ",
+			   b->number);
+      }
+  }
+
+  /* Now we can insert.  */
+  update_global_location_list (UGLL_MAY_INSERT);
+}
 
 /* Reset the thread number of this breakpoint:
 
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 526a2464dc7..8f2b9447531 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -570,15 +570,15 @@ enum print_stop_action
 
 struct breakpoint_ops
 {
-  /* Create SALs from location spec, storing the result in
-     linespec_result.
-
-     For an explanation about the arguments, see the function
-     `create_sals_from_location_spec_default'.
+  /* Create SALs from LOCSPEC, storing the result in linespec_result
+     CANONICAL.  If SEARCH_PSPACE is not nullptr then only results in the
+     corresponding program space are returned.  If SEARCH_PSPACE is nullptr
+     then results for all program spaces are returned.
 
      This function is called inside `create_breakpoint'.  */
   void (*create_sals_from_location_spec) (location_spec *locspec,
-					  struct linespec_result *canonical);
+					  linespec_result *canonical,
+					  program_space *search_pspace);
 
   /* This method will be responsible for creating a breakpoint given its SALs.
      Usually, it just calls `create_breakpoints_sal' (for ordinary
@@ -710,8 +710,15 @@ struct breakpoint : public intrusive_list_node<breakpoint>
 
   /* Reevaluate a breakpoint.  This is necessary after symbols change
      (e.g., an executable or DSO was loaded, or the inferior just
-     started).  */
-  virtual void re_set ()
+     started).
+
+     If not nullptr, then FILTER_PSPACE is the program space in which
+     symbols may have changed, we only need to add new locations in
+     FILTER_PSPACE.
+
+     If FILTER_PSPACE is nullptr then all program spaces may have changed,
+     new locations need to be searched for in every program space.  */
+  virtual void re_set (program_space *filter_pspace)
   {
     /* Nothing to re-set.  */
   }
@@ -955,7 +962,7 @@ struct code_breakpoint : public breakpoint
   /* Add a location for SAL to this breakpoint.  */
   bp_location *add_location (const symtab_and_line &sal);
 
-  void re_set () override;
+  void re_set (program_space *pspace) override;
   int insert_location (struct bp_location *) override;
   int remove_location (struct bp_location *,
 		       enum remove_bp_reason reason) override;
@@ -977,7 +984,7 @@ struct code_breakpoint : public breakpoint
      struct program_space *search_pspace);
 
   /* Helper method that does the basic work of re_set.  */
-  void re_set_default ();
+  void re_set_default (program_space *pspace);
 
   /* Find the SaL locations corresponding to the given LOCATION.
      On return, FOUND will be 1 if any SaL was found, zero otherwise.  */
@@ -999,7 +1006,7 @@ struct watchpoint : public breakpoint
 {
   using breakpoint::breakpoint;
 
-  void re_set () override;
+  void re_set (program_space *pspace) override;
   int insert_location (struct bp_location *) override;
   int remove_location (struct bp_location *,
 		       enum remove_bp_reason reason) override;
diff --git a/gdb/testsuite/gdb.mi/new-ui-bp-deleted.exp b/gdb/testsuite/gdb.mi/new-ui-bp-deleted.exp
index 57e69ef6240..3afc1787026 100644
--- a/gdb/testsuite/gdb.mi/new-ui-bp-deleted.exp
+++ b/gdb/testsuite/gdb.mi/new-ui-bp-deleted.exp
@@ -76,8 +76,12 @@ foreach_mi_ui_mode mode {
     set loc2 [make_bp_loc "$::decimal\\.2"]
 
     # Create the inferior-specific breakpoint.
-    mi_create_breakpoint_multi "-g i2 foo" "create breakpoint in inferior 2" \
-	-inferior "2" -locations "\\\[$loc1,$loc2\\\]"
+    mi_create_breakpoint "-g i2 foo" "create breakpoint in inferior 2" \
+	-number "$decimal" \
+	-type "breakpoint" \
+	-enabled "y" \
+	-func "foo" \
+	-inferior "2"
     set bpnum [mi_get_valueof "/d" "\$bpnum" "INVALID"]
 
     if {$mode eq "separate"} {
diff --git a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
index 4889c31aff3..b39745bdf17 100644
--- a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
+++ b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
@@ -370,7 +370,7 @@ proc test_continue_to_start { mode inf } {
 			    "thread $inf.2 stops MI"
 		    } else {
 			mi_expect_stop "breakpoint-hit" "child_sub_function" \
-			    "" "$srcfile" "$decimal" {"" "disp=\"del\"" "locno=\"[0-9]+\""} \
+			    "" "$srcfile" "$decimal" {"" "disp=\"del\""} \
 			    "thread $inf.2 stops MI"
 		    }
 		}
@@ -439,7 +439,7 @@ proc_with_prefix test_setup { mode } {
 
 	with_spawn_id $mi_spawn_id {
 	    mi_expect_stop "breakpoint-hit" "main" "" "$srcfile" "$decimal" \
-		{"" "disp=\"del\"" "locno=\"[0-9]+\""} "main stop"
+		{"" "disp=\"del\""} "main stop"
 	}
 
 	# Consume CLI output.
diff --git a/gdb/testsuite/gdb.multi/bp-thread-specific.exp b/gdb/testsuite/gdb.multi/bp-thread-specific.exp
index 85c08f44a2c..68001e92044 100644
--- a/gdb/testsuite/gdb.multi/bp-thread-specific.exp
+++ b/gdb/testsuite/gdb.multi/bp-thread-specific.exp
@@ -50,7 +50,7 @@ gdb_test "info threads" \
 # locations ('foo' in both inferiors) even though only one of those
 # locations will ever trigger ('foo' in inferior 2).
 gdb_test "break foo thread 2.1" \
-    "Breakpoint $decimal at $hex: foo\\. \\(2 locations\\)"
+    "Breakpoint $decimal at $hex: file \[^\r\n\]+$srcfile, line $decimal\\."
 
 set bpnum [get_integer_valueof "\$bpnum" "INVALID"]
 
@@ -58,10 +58,7 @@ set bpnum [get_integer_valueof "\$bpnum" "INVALID"]
 # earlier breakpoint.  Check that the thread-id used when describing
 # the earlier breakpoints is correct.
 gdb_test "break foo thread 1.1" \
-    [multi_line \
-	 "Note: breakpoint $bpnum \\(thread 2.1\\) also set at pc $hex\\." \
-	 "Note: breakpoint $bpnum \\(thread 2.1\\) also set at pc $hex\\." \
-	 "Breakpoint $decimal at $hex: foo\\. \\(2 locations\\)"]
+    "Breakpoint $decimal at $hex: file \[^\r\n\]+$srcfile, line $decimal\\."
 
 # Save the breakpoints into a file.
 if {[is_remote host]} {
diff --git a/gdb/testsuite/gdb.multi/inferior-specific-bp.exp b/gdb/testsuite/gdb.multi/inferior-specific-bp.exp
index b8aceabcad6..dda167dd39f 100644
--- a/gdb/testsuite/gdb.multi/inferior-specific-bp.exp
+++ b/gdb/testsuite/gdb.multi/inferior-specific-bp.exp
@@ -105,16 +105,8 @@ proc check_info_breakpoints { testname bp_number expected_loc_count } {
 # Create an inferior-specific breakpoint.  Use gdb_test instead of
 # gdb_breakpoint here as we want to check the breakpoint was placed in
 # multiple locations.
-#
-# Currently GDB still places inferior specific breakpoints into every
-# inferior, just like it does with thread specific breakpoints.
-# Hopefully this will change in the future, at which point, this test
-# will need updating.
-#
-# Two of these locations are in inferior 1, while the third is in
-# inferior 2.
 gdb_test "break foo inferior 1" \
-    "Breakpoint $decimal at $hex: foo\\. \\(3 locations\\)"
+    "Breakpoint $decimal at $hex: foo\\. \\(2 locations\\)"
 set bp_number [get_integer_valueof "\$bpnum" "INVALID" \
 		  "get b/p number for inferior specific breakpoint"]
 
@@ -123,7 +115,7 @@ set location_count 0
 set saw_inf_cond false
 
 check_info_breakpoints "first check for inferior specific breakpoint" \
-    $bp_number 3
+    $bp_number 2
 
 # Create a multi-inferior breakpoint to stop at.
 gdb_breakpoint "stop_breakpt" message
diff --git a/gdb/testsuite/gdb.multi/multi-target-continue.exp b/gdb/testsuite/gdb.multi/multi-target-continue.exp
index bf19cc00968..a1bffb7b613 100644
--- a/gdb/testsuite/gdb.multi/multi-target-continue.exp
+++ b/gdb/testsuite/gdb.multi/multi-target-continue.exp
@@ -30,7 +30,7 @@ proc test_continue {non-stop} {
 
     proc set_break {inf} {
 	gdb_test "break function${inf} thread ${inf}.1" \
-	"Breakpoint .* function${inf}\\..*"
+	    "Breakpoint ${::decimal} at ${::hex}: file .*, line ${::decimal}\\."
     }
 
     # Select inferior INF, and then run to a breakpoint on inferior
diff --git a/gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp b/gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp
index 64645b8ec8a..51fd70b018a 100644
--- a/gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp
+++ b/gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp
@@ -52,12 +52,12 @@ proc test_ping_pong_next {} {
     gdb_test "thread 1.1" "Switching to thread 1.1 .*"
 
     gdb_test "break $srcfile:$line1 thread 1.1" \
-	"Breakpoint .*$srcfile:$line1\\..*"
+	"Breakpoint .*$srcfile, line $line1\\."
 
     gdb_test "continue" "hit Breakpoint .*"
 
     gdb_test "break $srcfile:$line2 thread 2.1" \
-	"Breakpoint .*$srcfile:$line2\\..*"
+	"Breakpoint .*$srcfile, line $line2\\."
 
     # Now block inferior 1 and issue "next".  We should stop at the
     # breakpoint for inferior 2, given schedlock off.
diff --git a/gdb/testsuite/gdb.multi/pending-bp-del-inferior.exp b/gdb/testsuite/gdb.multi/pending-bp-del-inferior.exp
index 5fcd1ef2e39..12c0a84bb02 100644
--- a/gdb/testsuite/gdb.multi/pending-bp-del-inferior.exp
+++ b/gdb/testsuite/gdb.multi/pending-bp-del-inferior.exp
@@ -129,10 +129,8 @@ proc do_bp_test { bp_type bp_pending } {
     } else {
 	set bp_pattern_before \
 	    [multi_line \
-		 "$bp_number\\s+breakpoint\\s+keep\\s+y\\s+<MULTIPLE>\\s*" \
-		 "\\s+stop only in [string_to_regexp $bp_restriction]" \
-		 "$bp_number\\.1\\s+y\\s+$::hex in $bp_func at \[^\r\n\]+ inf 1" \
-		 "$bp_number\\.2\\s+y\\s+$::hex in $bp_func at \[^\r\n\]+ inf 2"]
+		 "$bp_number\\s+breakpoint\\s+keep\\s+y\\s+$::hex in $bp_func at \[^\r\n\]+ inf 1" \
+		 "\\s+stop only in [string_to_regexp $bp_restriction]"]
 
 	set bp_pattern_after \
 	    [multi_line \
diff --git a/gdb/testsuite/gdb.multi/pending-bp.exp b/gdb/testsuite/gdb.multi/pending-bp.exp
index 478d8d7c037..aeb8c2c886e 100644
--- a/gdb/testsuite/gdb.multi/pending-bp.exp
+++ b/gdb/testsuite/gdb.multi/pending-bp.exp
@@ -72,6 +72,48 @@ proc do_test_setup { inf_1_stop inf_2_stop } {
     return true
 }
 
+# Create a breakpoint on the function 'foo' in THREAD.  It is expected
+# that the breakpoint created will be pending, this is checked by
+# running the 'info breakpoints' command.
+#
+# Returns the number for the newly created breakpoint.
+proc do_create_pending_foo_breakpoint { {thread "1.1"} } {
+    gdb_test "break foo thread $thread" \
+	[multi_line \
+	     "Function \"foo\" not defined\\." \
+	     "Breakpoint $::decimal \\(foo\\) pending\."] \
+	"set pending thread-specific breakpoint"
+    set bpnum [get_integer_valueof "\$bpnum" "*INVALID*" \
+		   "get number for thread-specific breakpoint on foo"]
+    gdb_test "info breakpoints $bpnum" \
+	[multi_line \
+	     "$bpnum\\s+breakpoint\\s+keep\\s+y\\s+<PENDING>\\s+foo" \
+	     "\\s+stop only in thread [string_to_regexp $thread]"] \
+	"check thread-specific breakpoint is initially pending"
+
+    return $bpnum
+}
+
+# Create a breakpoint on the function 'foo' in THREAD.  It is expected
+# that the breakpoint created will not be pending, this is checked by
+# running the 'info breakpoints' command.
+#
+# Returns the number for the newly created breakpoint.
+proc do_create_foo_breakpoint { {thread "1.1"} } {
+    gdb_test "break foo thread $thread" \
+	"Breakpoint $::decimal at $::hex" \
+	"set thread-specific breakpoint"
+    set bpnum [get_integer_valueof "\$bpnum" "*INVALID*" \
+		   "get number for thread-specific breakpoint on foo"]
+    gdb_test "info breakpoints $bpnum" \
+	[multi_line \
+	     "$bpnum\\s+breakpoint\\s+keep\\s+y\\s+$::hex\\s+<foo\[^>\]*> inf $::decimal" \
+	     "\\s+stop only in thread [string_to_regexp $thread]"] \
+	"check thread-specific breakpoint is initially pending"
+
+    return $bpnum
+}
+
 # Check that when a breakpoint is in the pending state, but that breakpoint
 # does have some locations (those locations themselves are pending), GDB
 # doesn't display the inferior list in the 'info breakpoints' output.
@@ -122,5 +164,169 @@ proc_with_prefix test_no_inf_display {} {
 	"check info breakpoints while breakpoint is pending"
 }
 
+# Setup two inferiors.  In #1 the symbol 'foo' has not yet been
+# loaded, while in #2 the symbol 'foo' has been loaded.
+#
+# Create a thread-specific breakpoint on 'foo' tied to a thread in
+# inferior #1, the breakpoint should be pending -- 'foo' is not yet
+# loaded in #1.
+#
+# Now move inferior #1 forward until 'foo' is loaded, check the
+# breakpoint is no longer pending.
+#
+# Move inferior #1 forward more until 'foo' is unloaded, check that
+# the breakpoint returns to the pending state.
+proc_with_prefix test_pending_toggle { } {
+
+    do_test_setup "Break before open" "Break before close"
+
+    set bpnum [do_create_pending_foo_breakpoint]
+
+    # Now return to inferior 1 and continue until the shared library is
+    # loaded, the breakpoint should become non-pending.
+    gdb_test "inferior 1" "Switching to inferior 1 .*" \
+	"switch back to inferior 1"
+    gdb_continue_to_breakpoint "stop in foo in inferior 1" "foo \\(\\) .*"
+
+    gdb_test "info breakpoint $bpnum" \
+	[multi_line \
+	     "$bpnum\\s+breakpoint\\s+keep\\s+y\\s+$::hex <foo\[^>\]*> inf 1" \
+	     "\\s+stop only in thread 1\\.1" \
+	     "\\s+breakpoint already hit 1 time"] \
+	"check thread-specific breakpoint is no longer pending"
+
+    gdb_breakpoint [gdb_get_line_number "Break after close"] temporary
+    gdb_continue_to_breakpoint "close library"
+    gdb_test "info breakpoints $bpnum" \
+	[multi_line \
+	     "$bpnum\\s+breakpoint\\s+keep\\s+y\\s+<PENDING>\\s+foo" \
+	     "\\s+stop only in thread 1\\.1" \
+	     "\\s+breakpoint already hit 1 time"] \
+	"check thread-specific breakpoint is pending again"
+}
+
+# Create a Python variable VAR and set it to the gdb.Breakpoint object
+# corresponding to the breakpoint numbered BPNUM.  If THREAD is not
+# the empty string then THREAD should be an integer, check that
+# gdb.Breakpoint.thread is set to the value of THREAD.  Otherwise, if
+# THREAD is the empty string, check that gdb.Breakpoint.thread is set
+# to None.
+proc py_find_breakpoint { var bpnum {thread ""} } {
+    gdb_test_no_output \
+	"python ${var}=\[b for b in gdb.breakpoints() if b.number == $bpnum\]\[0\]" \
+	"find Python gdb.Breakpoint object"
+    if { $thread ne "" } {
+	gdb_test_no_output "python assert(${var}.thread == ${thread})" \
+	    "check thread attribute is currently correct"
+    } else {
+	gdb_test_no_output "python assert(${var}.thread is None)" \
+	    "check thread attribute is currently correct"
+    }
+}
+
+# Setup two inferiors.  In #1 the symbol 'foo' has not yet been
+# loaded, while in #2 the symbol 'foo' has been loaded.
+#
+# Create a thread-specific breakpoint on 'foo' tied to a thread in
+# inferior #1, the breakpoint should be pending -- 'foo' is not yet
+# loaded in #1.
+#
+# Use Python to change the thread of the thread-specific breakpoint to
+# a thread in inferior #2, at this point the thread should gain a
+# location and become non-pending.
+#
+# Set the thread back to a thread in inferior #1, the breakpoint
+# should return to the pending state.
+proc_with_prefix py_test_toggle_thread {} {
+    do_test_setup "Break before open" "Break after open"
+
+    set bpnum [do_create_pending_foo_breakpoint]
+
+    py_find_breakpoint "bp" $bpnum 1
+
+    gdb_test_no_output "python bp.thread = 2" \
+	"change thread on thread-specific breakpoint"
+    gdb_test "info breakpoint $bpnum" \
+	[multi_line \
+	     "$bpnum\\s+breakpoint\\s+keep\\s+y\\s+$::hex <foo\[^>\]*> inf 2" \
+	     "\\s+stop only in thread 2\\.1"] \
+	"check thread-specific breakpoint now has a location"
+
+    gdb_test_no_output "set call_count = 2" "set call_count in inferior 2"
+    gdb_continue_to_breakpoint "stop at foo in inferior 2" "foo \\(\\) .*"
+
+    gdb_test_no_output "python bp.thread = 1" \
+	"restore thread on thread-specific breakpoint"
+    gdb_test "info breakpoints $bpnum" \
+	[multi_line \
+	     "$bpnum\\s+breakpoint\\s+keep\\s+y\\s+<PENDING>\\s+foo" \
+	     "\\s+stop only in thread 1\\.1" \
+	     "\\s+breakpoint already hit 1 time"] \
+	"check thread-specific breakpoint has returned to pending"
+
+    gdb_breakpoint [gdb_get_line_number "Break after close"] temporary
+    gdb_continue_to_breakpoint "stop after close in inferior 2" \
+	".* Break after close\\. .*"
+
+    gdb_test "inferior 1" "Switching to inferior 1 .*" \
+	"switch to inferior 1"
+    gdb_continue_to_breakpoint "stop at foo in inferior 1" "foo \\(\\) .*"
+}
+
+# Setup two inferiors.  Both inferiors have the symbol 'foo'
+# available.
+#
+# Create a thread-specific breakpoint on 'foo' tied to a thread in
+# inferior #1, the breakpoint should not be pending, but will only
+# have a single location, the location in inferior #1.
+#
+# Use Python to change the thread of the thread-specific breakpoint to
+# None.  At this point the breakpoint should gain a second location, a
+# location in inferior #2.
+proc_with_prefix py_test_clear_thread {} {
+    do_test_setup "Break after open" "Break after open"
+
+    set bpnum [do_create_foo_breakpoint]
+
+    py_find_breakpoint "bp" $bpnum 1
+
+    gdb_test_no_output "python bp.thread = None" \
+	"clear thread on thread-specific breakpoint"
+    gdb_test "info breakpoints $bpnum" \
+	[multi_line \
+	     "${bpnum}\\s+breakpoint\\s+keep y\\s+<MULTIPLE>\\s*" \
+	     "${bpnum}\\.1\\s+y\\s+${::hex}\\s+<foo\[^>\]*> inf $::decimal" \
+	     "${bpnum}\\.2\\s+y\\s+${::hex}\\s+<foo\[^>\]*> inf $::decimal"] \
+	"check for a location in both inferiors"
+
+    gdb_continue_to_breakpoint "stop at foo in inferior 2" "foo \\(\\) .*"
+    gdb_test_no_output "set call_count = 2" "set call_count in inferior 2"
+
+    gdb_test "inferior 1" "Switching to inferior 1 .*" \
+	"switch to inferior 1"
+    gdb_continue_to_breakpoint "stop at foo in inferior 1" "foo \\(\\) .*"
+    gdb_test_no_output "set call_count = 2" "set call_count in inferior 1"
+
+    gdb_test_no_output "python bp.thread = 2"
+    gdb_test "info breakpoints $bpnum" \
+	[multi_line \
+	     "${bpnum}\\s+breakpoint\\s+keep y\\s+${::hex}\\s+<foo\[^>\]*> inf 2" \
+	     "\\s+stop only in thread 2\\.1" \
+	     "\\s+breakpoint already hit 2 times"] \
+	"check for a location only in inferior 2"
+
+    gdb_breakpoint [gdb_get_line_number "Break after close"] temporary
+    gdb_continue_to_breakpoint "stop after close in inferior 1" \
+	".* Break after close\\. .*"
+
+    gdb_test "inferior 2" "Switching to inferior 2 .*" \
+	"switch back to inferior 2"
+    gdb_continue_to_breakpoint "stop at foo again in inferior 2" \
+	"foo \\(\\) .*"
+}
+
 # Run all the tests.
 test_no_inf_display
+test_pending_toggle
+py_test_toggle_thread
+py_test_clear_thread
diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp
index 18fc4970fe7..34c270309de 100644
--- a/gdb/testsuite/gdb.multi/tids.exp
+++ b/gdb/testsuite/gdb.multi/tids.exp
@@ -433,11 +433,13 @@ if { [allow_python_tests] } {
 
 	gdb_py_test_silent_cmd "python bp = gdb.breakpoints()\[0\]" \
 	    "get python breakpoint" 0
-	gdb_test "python bp.thread = 6" "thread = 6" \
+	gdb_test_no_output "python bp.thread = 6" \
 	    "make breakpoint thread-specific with python"
 	# Check that the inferior-qualified ID is correct.
 	gdb_test "info breakpoint" \
-	    "stop only in thread 1.3\r\n.*" \
+	    [multi_line \
+		 "$decimal\\s+\[^\r\n\]+ in thread_function1 at \[^\r\n\]+" \
+		 "\\s+stop only in thread 1\\.3"] \
 	    "thread specific breakpoint right thread"
     }
 }
