diff --git a/gdb/symfile.c b/gdb/symfile.c
index c2844eb88a5..e3aa81fbc0c 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -969,20 +969,15 @@ syms_from_objfile (struct objfile *objfile,
 static void
 finish_new_objfile (struct objfile *objfile, symfile_add_flags add_flags)
 {
-  /* If this is the main symbol file we have to clean up all users of the
-     old main symbol file.  Otherwise it is sufficient to fixup all the
-     breakpoints that may have been redefined by this symbol file.  */
-  if (add_flags & SYMFILE_MAINLINE)
-    {
-      /* OK, make it the "real" symbol file.  */
-      current_program_space->symfile_object_file = objfile;
+  /* If this is the main symbol file then record it as such in the program
+     space.  Don't record any separate debug files loaded as a consequence
+     of loading the main symbol file though.  */
+  if (add_flags & SYMFILE_MAINLINE
+      && objfile->separate_debug_objfile_backlink == nullptr)
+    current_program_space->symfile_object_file = objfile;
 
-      clear_symtab_users (add_flags);
-    }
-  else if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
-    {
-      breakpoint_re_set ();
-    }
+  if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
+    breakpoint_re_set ();
 
   /* We're done reading the symbol file; finish off complaints.  */
   clear_complaints ();
@@ -1047,7 +1042,17 @@ symbol_file_add_with_addrs (const gdb_bfd_ref_ptr &abfd, const char *name,
     error (_("Not confirmed."));
 
   if (mainline)
-    flags |= OBJF_MAINLINE;
+    {
+      flags |= OBJF_MAINLINE;
+
+      /* Before we create the new objfile, or load any debug symbols,
+	 discard any existing cached symbols.  Don't reset breakpoints at
+	 this point as we haven't discarded the previous main objfile yet,
+	 and we'd only end up resolving the breakpoints against the old
+	 symbols.  The breakpoints will be reset in finish_new_objfile.  */
+      if (parent == nullptr)
+	clear_symtab_users (add_flags | SYMFILE_DEFER_BP_RESET);
+    }
 
   objfile *objfile
     = objfile::make (abfd, current_program_space, name, flags, parent);
diff --git a/gdb/testsuite/gdb.python/py-section-script.exp b/gdb/testsuite/gdb.python/py-section-script.exp
index a3b9631ade7..d1a5a901570 100644
--- a/gdb/testsuite/gdb.python/py-section-script.exp
+++ b/gdb/testsuite/gdb.python/py-section-script.exp
@@ -183,4 +183,45 @@ foreach_with_prefix variant {plain compressed} {
 	gdb_test "info auto-load python-scripts no-script-matches-this" \
 	    "No auto-load scripts matching no-script-matches-this."
     }
+
+    # Unlike eu-strip, objcopy moves the .debug_gdb_scripts into the .debug
+    # file, removing it from the executable.  GDB should still load the
+    # script though, just when it loads the symbol file, not the main
+    # executable.
+    with_test_prefix "sepdebug from objcopy" {
+	clean_restart
+
+	set objcopy_testfile ${the_testfile}-objcopy
+	set objcopy_binfile [standard_output_file $objcopy_testfile]
+	file copy -force $the_binfile $objcopy_binfile
+
+	if { [gdb_gnu_strip_debug $objcopy_binfile] != 0 } {
+	    fail "strip $objcopy_testfile debuginfo"
+	    return
+	}
+
+	set_auto_load_safe_path $remote_python_file \
+	    [file dirname ${objcopy_binfile}]
+	gdb_load $objcopy_binfile
+
+	# Verify gdb loaded each script and they appear once in the list.
+	gdb_test_multiple "info auto-load python-scripts" "verify scripts loaded" {
+	    -re -wrap "Yes.*${testfile}.py.*Yes.*inlined-script.*" {
+		pass $gdb_test_name
+	    }
+	    -re -wrap "${testfile}.py.*${testfile}.py.*" {
+		fail $gdb_test_name
+	    }
+	    -re -wrap "inlined-script.*inlined-script.*" {
+		fail $gdb_test_name
+	    }
+	}
+
+	# Again, with a regexp this time.
+	gdb_test "info auto-load python-scripts ${testfile}" "Yes.*${testfile}.py.*"
+
+	# Again, with a regexp that matches no scripts.
+	gdb_test "info auto-load python-scripts no-script-matches-this" \
+	    "No auto-load scripts matching no-script-matches-this."
+    }
 }
