diff --git a/gdb/testsuite/gdb.arch/s390-multiarch.exp b/gdb/testsuite/gdb.arch/s390-multiarch.exp
index 28545d7..9d45e04 100644
--- a/gdb/testsuite/gdb.arch/s390-multiarch.exp
+++ b/gdb/testsuite/gdb.arch/s390-multiarch.exp
@@ -51,7 +51,7 @@ proc compile_and_dump {variant ccopts binfile} {
     pass $test
 
     set test "create core file ($variant)"
-    set corefile [core_find $binfile]
+    set corefile [run_and_get_core $binfile]
     if {$corefile == ""} {
 	fail $test
 	return {}
diff --git a/gdb/testsuite/gdb.arch/s390-vregs.exp b/gdb/testsuite/gdb.arch/s390-vregs.exp
index d2c31e1..d5ed6f2 100644
--- a/gdb/testsuite/gdb.arch/s390-vregs.exp
+++ b/gdb/testsuite/gdb.arch/s390-vregs.exp
@@ -185,14 +185,12 @@ gdb_exit
 
 # Find the core file and rename it (avoid accumulating core files).
 
-set cores [glob -nocomplain -directory $coredir *core*]
-if {[llength $cores] != 1} {
+set destcore [find_core $binfile $coredir]
+if {$destcore == ""} {
     untested "core file not found"
     remote_exec build "rm -rf $coredir"
     return -1
 }
-set destcore [standard_output_file ${testfile}.core]
-remote_exec build "mv [file join $coredir [lindex $cores 0]] $destcore"
 remote_exec build "rm -rf $coredir"
 
 # Restart gdb and load the core file.  Compare the VRs.
diff --git a/gdb/testsuite/gdb.base/bigcore.exp b/gdb/testsuite/gdb.base/bigcore.exp
index dbd8c00..ba8480a 100644
--- a/gdb/testsuite/gdb.base/bigcore.exp
+++ b/gdb/testsuite/gdb.base/bigcore.exp
@@ -135,16 +135,7 @@ gdb_test "signal SIGABRT" "Program terminated with signal SIGABRT, .*"
 set timeout $oldtimeout
 
 # Find the corefile
-set file ""
-foreach pat [list core.${inferior_pid} ${testfile}.core core] {
-    set names [glob -nocomplain [standard_output_file $pat]]
-    if {[llength $names] == 1} {
-	set file [lindex $names 0]
-	remote_exec build "mv $file $corefile"
-	break
-    }
-}
-
+set file [find_core $binfile [file dirname $corefile] $corefile]
 if { $file == "" } {
     untested "can't generate a core file"
     return 0
diff --git a/gdb/testsuite/gdb.base/break-interp.exp b/gdb/testsuite/gdb.base/break-interp.exp
index 3a6d9a9..49967c6 100644
--- a/gdb/testsuite/gdb.base/break-interp.exp
+++ b/gdb/testsuite/gdb.base/break-interp.exp
@@ -201,7 +201,7 @@ proc test_core {file displacement} {
     with_test_prefix "core" {
 	global srcdir subdir gdb_prompt expect_out
 
-	set corefile [core_find $file {} "segv"]
+	set corefile [run_and_get_core $file "segv"]
 	if {$corefile == ""} {
 	    return
 	}
diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp
index 21b974f..a9f7115 100644
--- a/gdb/testsuite/gdb.base/corefile.exp
+++ b/gdb/testsuite/gdb.base/corefile.exp
@@ -34,7 +34,7 @@ if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} {
     return -1
 }
 
-set corefile [core_find $binfile {coremmap.data}]
+set corefile [run_and_get_core $binfile]
 if {$corefile == ""} {
     return 0
 }
diff --git a/gdb/testsuite/gdb.threads/corethreads.exp b/gdb/testsuite/gdb.threads/corethreads.exp
index f7d85fb..0f80625 100644
--- a/gdb/testsuite/gdb.threads/corethreads.exp
+++ b/gdb/testsuite/gdb.threads/corethreads.exp
@@ -26,7 +26,7 @@ if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executa
      return -1
 }
 
-set corefile [core_find $binfile]
+set corefile [run_and_get_core $binfile]
 if {$corefile == ""} {
     return 0
 }
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 8af1b77..1fd0009 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -5795,71 +5795,90 @@ if {[info exists GDB_PARALLEL]} {
     }
 }
 
-proc core_find {binfile {deletefiles {}} {arg ""}} {
-    global objdir subdir
+# Run COMMAND in directory DIR.  Suppress the command's output and ignore
+# its exit code.  Return 0 if the command could be executed, nonzero
+# otherwise.
+
+proc exec_in_dir {dir command} {
+    set err [catch {system "(cd ${dir}; ${command}; true) >/dev/null 2>&1"}]
+    if {$err} {
+	verbose -log "Failed executing \"${command}\"."
+    } else {
+	verbose -log "Executed: \"${command}\"."
+    }
+    return $err
+}
 
-    set destcore "$binfile.core"
-    file delete $destcore
+# Run a program that will dump core, then try to locate the core file.
+# Return the core file's filename, or "", if none was found.
 
-    # Create a core file named "$destcore" rather than just "core", to
-    # avoid problems with sys admin types that like to regularly prune all
-    # files named "core" from the system.
-    #
-    # Arbitrarily try setting the core size limit to "unlimited" since
-    # this does not hurt on systems where the command does not work and
-    # allows us to generate a core on systems where it does.
-    #
-    # Some systems append "core" to the name of the program; others append
-    # the name of the program to "core"; still others (like Linux, as of
-    # May 2003) create cores named "core.PID".  In the latter case, we
-    # could have many core files lying around, and it may be difficult to
-    # tell which one is ours, so let's run the program in a subdirectory.
-    set found 0
+proc run_and_get_core {binfile {arg ""}} {
+    if {[is_remote target]} {
+	warning "Can not generate core dump on remote target."
+	return ""
+    }
+    # Run the program in a subdirectory, to prevent generated files or
+    # core files from clashing, and to simplify clean-up.
     set coredir [standard_output_file coredir.[getpid]]
     file mkdir $coredir
-    catch "system \"(cd ${coredir}; ulimit -c unlimited; ${binfile} ${arg}; true) >/dev/null 2>&1\""
-    #      remote_exec host "${binfile}"
+
+    set err [exec_in_dir $coredir "ulimit -c unlimited; ${binfile} ${arg}"]
+    if {$err} {
+	# Try again without "ulimit -c", for shells that don't understand
+	# this.
+	set err [exec_in_dir $coredir "${binfile} ${arg}"]
+    }
+    if {$err} {
+	set destcore ""
+	warning "Could not invoke ${binfile} for generating a core dump"
+    } else {
+	set destcore [find_core $binfile $coredir]
+    }
+
+    # Clean up after ourselves.
+    file delete -force $coredir
+
+    return $destcore
+}
+
+# Find a core file that should have been created by the executable BINFILE
+# in the directory COREDIR.  Move it to "BINFILE.core", or to DESTCORE, if
+# specified.  Return that path name, or "" if no core file was found.
+
+proc find_core {binfile coredir {destcore ""}} {
+    if {[is_remote target]} {
+	warning "Can not access remote core file."
+	return ""
+    }
+    global objdir subdir
+
+    if {$destcore eq ""} {
+	set destcore "$binfile.core"
+    }
+    file delete $destcore
+
     foreach i "${coredir}/core ${coredir}/core.coremaker.c ${binfile}.core" {
-	if [remote_file build exists $i] {
-	    remote_exec build "mv $i $destcore"
-	    set found 1
+	if [file exists $i] {
+	    file rename $i $destcore
+	    return $destcore
 	}
     }
     # Check for "core.PID".
-    if { $found == 0 } {
-	set names [glob -nocomplain -directory $coredir core.*]
-	if {[llength $names] == 1} {
-	    set corefile [file join $coredir [lindex $names 0]]
-	    remote_exec build "mv $corefile $destcore"
-	    set found 1
-	}
-    }
-    if { $found == 0 } {
-	# The braindamaged HPUX shell quits after the ulimit -c above
-	# without executing ${binfile}.  So we try again without the
-	# ulimit here if we didn't find a core file above.
-	# Oh, I should mention that any "braindamaged" non-Unix system has
-	# the same problem. I like the cd bit too, it's really neat'n stuff.
-	catch "system \"(cd ${objdir}/${subdir}; ${binfile}; true) >/dev/null 2>&1\""
-	foreach i "${objdir}/${subdir}/core ${objdir}/${subdir}/core.coremaker.c ${binfile}.core" {
-	    if [remote_file build exists $i] {
-		remote_exec build "mv $i $destcore"
-		set found 1
-	    }
+    set names [glob -nocomplain -directory $coredir core.*]
+    if {[llength $names] == 1} {
+	set corefile [file join $coredir [lindex $names 0]]
+	file rename $corefile $destcore
+	return $destcore
+    }
+    foreach i "${objdir}/${subdir}/core ${objdir}/${subdir}/core.coremaker.c ${binfile}.core" {
+	if [file exists $i] {
+	    file rename $i $destcore
+	    return $destcore
 	}
     }
 
-    # Try to clean up after ourselves. 
-    foreach deletefile $deletefiles {
-	remote_file build delete [file join $coredir $deletefile]
-    }
-    remote_exec build "rmdir $coredir"
-	
-    if { $found == 0  } {
-	warning "can't generate a core file - core tests suppressed - check ulimit -c"
-	return ""
-    }
-    return $destcore
+    warning "Can not locate core dump generated by \"[file tail $binfile]\"."
+    return ""
 }
 
 # gdb_target_symbol_prefix compiles a test program and then examines
