diff --git a/gdb/infcall.c b/gdb/infcall.c
index 8b26f541de6..e6b24ff5310 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -918,12 +918,20 @@ run_inferior_call (std::unique_ptr<call_thread_fsm> sm,
       current_ui->register_file_handler ();
     }
 
-  /* If the infcall does NOT succeed, normal_stop will have already
-     finished the thread states.  However, on success, normal_stop
-     defers here, so that we can set back the thread states to what
-     they were before the call.  Note that we must also finish the
-     state of new threads that might have spawned while the call was
-     running.  The main cases to handle are:
+  /* Sync the user/frontend thread states from the internal thread
+     states.  proceed marked threads in resume_ptid as THREAD_RUNNING
+     for this infcall; we must now sync them back, regardless of how
+     the call ended.  For the success path and for the unwind paths
+     (unwind-on-{signal,timeout,terminating-exception}),
+     call_thread_fsm::should_notify_stop returns false and normal_stop
+     is skipped -- this call is the canonical place to do the sync.
+     For other failure paths normal_stop does run and has already
+     finished the thread state; finish_thread_state is idempotent, so
+     calling it again here is harmless.  Note that we must also finish
+     the state of new threads that might have spawned while the call
+     was running.
+
+     The main cases to handle are:
 
      - "(gdb) print foo ()", or any other command that evaluates an
      expression at the prompt.  (The thread was marked stopped before.)
@@ -934,8 +942,7 @@ run_inferior_call (std::unique_ptr<call_thread_fsm> sm,
      evaluates true and thus we'll present a user-visible stop is
      decided elsewhere.  */
   if (!was_running
-      && call_thread_ptid == inferior_ptid
-      && stop_stack_dummy == STOP_STACK_DUMMY)
+      && call_thread_ptid == inferior_ptid)
     finish_thread_state (call_thread->inf->process_target (),
 			 user_visible_resume_ptid (0));
 
diff --git a/gdb/testsuite/gdb.base/infcall-timeout.exp b/gdb/testsuite/gdb.base/infcall-timeout.exp
index 37aa6c0ef54..99d29624337 100644
--- a/gdb/testsuite/gdb.base/infcall-timeout.exp
+++ b/gdb/testsuite/gdb.base/infcall-timeout.exp
@@ -86,6 +86,19 @@ proc run_test { target_async target_non_stop non_stop unwind } {
 	gdb_test "bt" \
 	    ".* function_that_never_returns .*<function called from gdb>.*"
     }
+
+    # After the infcall, the thread should be stopped.  Regression
+    # test for PR gdb/34148.
+    if {$non_stop} {
+	# Check the main thread only, in case we have system-spawned
+	# threads.
+	set thread_filter "1"
+    } else {
+	set thread_filter ""
+    }
+    gdb_test "info threads -running $thread_filter" \
+	"No threads matched\\." \
+	"thread is stopped"
 }
 
 foreach_with_prefix target_async { "on" "off" } {
diff --git a/gdb/testsuite/gdb.base/unwindonsignal.exp b/gdb/testsuite/gdb.base/unwindonsignal.exp
index aed8ef6f4c7..2ae8cc4a6dd 100644
--- a/gdb/testsuite/gdb.base/unwindonsignal.exp
+++ b/gdb/testsuite/gdb.base/unwindonsignal.exp
@@ -86,3 +86,13 @@ gdb_test_multiple "maint print dummy-frames" \
 	pass $gdb_test_name
     }
 }
+
+# After the unwound infcall, the thread should be stopped, and a
+# subsequent resumption command should be accepted.  Regression test
+# for PR gdb/34148.
+
+gdb_test "info threads -running" \
+    "No threads matched\\." \
+    "thread is stopped"
+
+gdb_continue_to_end "after unwound infcall"
diff --git a/gdb/testsuite/gdb.cp/gdb2495.exp b/gdb/testsuite/gdb.cp/gdb2495.exp
index aa5a2a16e43..60396494161 100644
--- a/gdb/testsuite/gdb.cp/gdb2495.exp
+++ b/gdb/testsuite/gdb.cp/gdb2495.exp
@@ -64,6 +64,12 @@ gdb_test "p exceptions.throw_function()" \
     "The program being debugged entered a std::terminate call, .*" \
     "call a function that raises an exception without a handler."
 
+# Make sure that the thread is stopped.  Regression test for PR
+# gdb/34148.
+gdb_test "info threads -running" \
+    "No threads matched\\." \
+    "thread is stopped"
+
 # Make sure that after rewinding we are back at the call parent.
 gdb_test "bt" \
     "#0  main.*" \
