- /* Find the name of the function we're about to complain about. */
- const char *name = NULL;
- {
- struct symbol *symbol = find_pc_function (funaddr);
- if (symbol)
- name = SYMBOL_PRINT_NAME (symbol);
- else
- {
- /* Try the minimal symbols. */
- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr);
- if (msymbol)
- name = SYMBOL_PRINT_NAME (msymbol);
- }
- if (name == NULL)
- {
- /* Can't use a cleanup here. It is discarded, instead use
- an alloca. */
- char *tmp = xstrprintf ("at %s", hex_string (funaddr));
- char *a = alloca (strlen (tmp) + 1);
- strcpy (a, tmp);
- xfree (tmp);
- name = a;
- }
- }
+ const char *name = get_function_name (funaddr,
+ name_buf, sizeof (name_buf));
+
+ discard_infcall_control_state (inf_status);
+
+ /* We could discard the dummy frame here if the program exited,
+ but it will get garbage collected the next time the program is
+ run anyway. */
+
+ switch (e.reason)
+ {
+ case RETURN_ERROR:
+ throw_error (e.error, _("%s\n\
+An error occurred while in a function called from GDB.\n\
+Evaluation of the expression containing the function\n\
+(%s) will be abandoned.\n\
+When the function is done executing, GDB will silently stop."),
+ e.message, name);
+ case RETURN_QUIT:
+ default:
+ throw_exception (e);
+ }
+ }
+
+ /* If the program has exited, or we stopped at a different thread,
+ exit and inform the user. */
+
+ if (! target_has_execution)
+ {
+ const char *name = get_function_name (funaddr,
+ name_buf, sizeof (name_buf));
+
+ /* If we try to restore the inferior status,
+ we'll crash as the inferior is no longer running. */
+ discard_infcall_control_state (inf_status);
+
+ /* We could discard the dummy frame here given that the program exited,
+ but it will get garbage collected the next time the program is
+ run anyway. */
+
+ error (_("The program being debugged exited while in a function "
+ "called from GDB.\n"
+ "Evaluation of the expression containing the function\n"
+ "(%s) will be abandoned."),
+ name);
+ }
+
+ if (! ptid_equal (call_thread_ptid, inferior_ptid))
+ {
+ const char *name = get_function_name (funaddr,
+ name_buf, sizeof (name_buf));
+
+ /* We've switched threads. This can happen if another thread gets a
+ signal or breakpoint while our thread was running.
+ There's no point in restoring the inferior status,
+ we're in a different thread. */
+ discard_infcall_control_state (inf_status);
+ /* Keep the dummy frame record, if the user switches back to the
+ thread with the hand-call, we'll need it. */
+ if (stopped_by_random_signal)
+ error (_("\
+The program received a signal in another thread while\n\
+making a function call from GDB.\n\
+Evaluation of the expression containing the function\n\
+(%s) will be abandoned.\n\
+When the function is done executing, GDB will silently stop."),
+ name);
+ else
+ error (_("\
+The program stopped in another thread while making a function call from GDB.\n\
+Evaluation of the expression containing the function\n\
+(%s) will be abandoned.\n\
+When the function is done executing, GDB will silently stop."),
+ name);
+ }
+
+ if (stopped_by_random_signal || stop_stack_dummy != STOP_STACK_DUMMY)
+ {
+ const char *name = get_function_name (funaddr,
+ name_buf, sizeof (name_buf));
+