/* Target-struct-independent code to start (run) and stop an inferior
process.
- Copyright (C) 1986-2016 Free Software Foundation, Inc.
+ Copyright (C) 1986-2017 Free Software Foundation, Inc.
This file is part of GDB.
fprintf_filtered (file, _("Follow exec mode is \"%s\".\n"), value);
}
-/* EXECD_PATHNAME is assumed to be non-NULL. */
+/* EXEC_FILE_TARGET is assumed to be non-NULL. */
static void
-follow_exec (ptid_t ptid, char *execd_pathname)
+follow_exec (ptid_t ptid, char *exec_file_target)
{
struct thread_info *th, *tmp;
struct inferior *inf = current_inferior ();
int pid = ptid_get_pid (ptid);
ptid_t process_ptid;
+ char *exec_file_host;
+ struct cleanup *old_chain;
/* This is an exec event that we actually wish to pay attention to.
Refresh our symbol table to the newly exec'd program, remove any
process_ptid = pid_to_ptid (pid);
printf_unfiltered (_("%s is executing new program: %s\n"),
target_pid_to_str (process_ptid),
- execd_pathname);
+ exec_file_target);
/* We've followed the inferior through an exec. Therefore, the
inferior has essentially been killed & reborn. */
breakpoint_init_inferior (inf_execd);
- if (*gdb_sysroot != '\0')
- {
- char *name = exec_file_find (execd_pathname, NULL);
+ exec_file_host = exec_file_find (exec_file_target, NULL);
+ old_chain = make_cleanup (xfree, exec_file_host);
- execd_pathname = (char *) alloca (strlen (name) + 1);
- strcpy (execd_pathname, name);
- xfree (name);
- }
+ /* If we were unable to map the executable target pathname onto a host
+ pathname, tell the user that. Otherwise GDB's subsequent behavior
+ is confusing. Maybe it would even be better to stop at this point
+ so that the user can specify a file manually before continuing. */
+ if (exec_file_host == NULL)
+ warning (_("Could not load symbols for executable %s.\n"
+ "Do you need \"set sysroot\"?"),
+ exec_file_target);
/* Reset the shared library package. This ensures that we get a
shlib event when the child reaches "_start", at which point the
inf = add_inferior_with_spaces ();
inf->pid = pid;
- target_follow_exec (inf, execd_pathname);
+ target_follow_exec (inf, exec_file_target);
set_current_inferior (inf);
set_current_program_space (inf->pspace);
gdb_assert (current_program_space == inf->pspace);
- /* That a.out is now the one to use. */
- exec_file_attach (execd_pathname, 0);
+ /* Attempt to open the exec file. SYMFILE_DEFER_BP_RESET is used
+ because the proper displacement for a PIE (Position Independent
+ Executable) main symbol file will only be computed by
+ solib_create_inferior_hook below. breakpoint_re_set would fail
+ to insert the breakpoints with the zero displacement. */
+ try_open_exec_file (exec_file_host, inf, SYMFILE_DEFER_BP_RESET);
- /* SYMFILE_DEFER_BP_RESET is used as the proper displacement for PIE
- (Position Independent Executable) main symbol file will get applied by
- solib_create_inferior_hook below. breakpoint_re_set would fail to insert
- the breakpoints with the zero displacement. */
-
- symbol_file_add (execd_pathname,
- (inf->symfile_flags
- | SYMFILE_MAINLINE | SYMFILE_DEFER_BP_RESET),
- NULL, 0);
-
- if ((inf->symfile_flags & SYMFILE_NO_READ) == 0)
- set_initial_language ();
+ do_cleanups (old_chain);
/* If the target can specify a description, read it. Must do this
after flipping to the new executable (because the target supplied
static struct step_over_info step_over_info;
/* Record the address of the breakpoint/instruction we're currently
- stepping over. */
+ stepping over.
+ N.B. We record the aspace and address now, instead of say just the thread,
+ because when we need the info later the thread may be running. */
static void
set_step_over_info (struct address_space *aspace, CORE_ADDR address,
int hw_step = 1;
if (execution_direction == EXEC_FORWARD
- && gdbarch_software_single_step_p (gdbarch)
- && gdbarch_software_single_step (gdbarch, get_current_frame ()))
- {
- hw_step = 0;
- }
+ && gdbarch_software_single_step_p (gdbarch))
+ hw_step = !insert_single_step_breakpoints (gdbarch);
+
return hw_step;
}
target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
target_resume (resume_ptid, step, sig);
+
+ target_commit_resume ();
}
/* Resume the inferior, but allow a QUIT. This is useful if the user
struct execution_control_state ecss;
struct execution_control_state *ecs = &ecss;
struct cleanup *old_chain;
+ struct cleanup *defer_resume_cleanup;
int started;
/* If we're stopped at a fork/vfork, follow the branch set by the
until the target stops again. */
tp->prev_pc = regcache_read_pc (regcache);
+ defer_resume_cleanup = make_cleanup_defer_target_commit_resume ();
+
started = start_step_over ();
if (step_over_info_valid_p ())
error (_("Command aborted."));
}
+ do_cleanups (defer_resume_cleanup);
+ target_commit_resume ();
+
discard_cleanups (old_chain);
/* Tell the event loop to wait for it to stop. If the target
const struct target_waitstatus *ws)
{
char *status_string = target_waitstatus_to_string (ws);
- struct ui_file *tmp_stream = mem_fileopen ();
- char *text;
+ string_file stb;
/* The text is split over several lines because it was getting too long.
Call fprintf_unfiltered (gdb_stdlog) once so that the text is still
output as a unit; we want only one timestamp printed if debug_timestamp
is set. */
- fprintf_unfiltered (tmp_stream,
- "infrun: target_wait (%d.%ld.%ld",
- ptid_get_pid (waiton_ptid),
- ptid_get_lwp (waiton_ptid),
- ptid_get_tid (waiton_ptid));
+ stb.printf ("infrun: target_wait (%d.%ld.%ld",
+ ptid_get_pid (waiton_ptid),
+ ptid_get_lwp (waiton_ptid),
+ ptid_get_tid (waiton_ptid));
if (ptid_get_pid (waiton_ptid) != -1)
- fprintf_unfiltered (tmp_stream,
- " [%s]", target_pid_to_str (waiton_ptid));
- fprintf_unfiltered (tmp_stream, ", status) =\n");
- fprintf_unfiltered (tmp_stream,
- "infrun: %d.%ld.%ld [%s],\n",
- ptid_get_pid (result_ptid),
- ptid_get_lwp (result_ptid),
- ptid_get_tid (result_ptid),
- target_pid_to_str (result_ptid));
- fprintf_unfiltered (tmp_stream,
- "infrun: %s\n",
- status_string);
-
- text = ui_file_xstrdup (tmp_stream, NULL);
+ stb.printf (" [%s]", target_pid_to_str (waiton_ptid));
+ stb.printf (", status) =\n");
+ stb.printf ("infrun: %d.%ld.%ld [%s],\n",
+ ptid_get_pid (result_ptid),
+ ptid_get_lwp (result_ptid),
+ ptid_get_tid (result_ptid),
+ target_pid_to_str (result_ptid));
+ stb.printf ("infrun: %s\n", status_string);
/* This uses %s in part to handle %'s in the text, but also to avoid
a gcc error: the format attribute requires a string literal. */
- fprintf_unfiltered (gdb_stdlog, "%s", text);
+ fprintf_unfiltered (gdb_stdlog, "%s", stb.c_str ());
xfree (status_string);
- xfree (text);
- ui_file_delete (tmp_stream);
}
/* Select a thread at random, out of those which are resumed and have
{
/* For CLI-like interpreters, print nothing. */
- if (ui_out_is_mi_like_p (uiout))
+ if (uiout->is_mi_like_p ())
{
- ui_out_field_string (uiout, "reason",
+ uiout->field_string ("reason",
async_reason_lookup (EXEC_ASYNC_END_STEPPING_RANGE));
}
}
print_signal_exited_reason (struct ui_out *uiout, enum gdb_signal siggnal)
{
annotate_signalled ();
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason", async_reason_lookup (EXEC_ASYNC_EXITED_SIGNALLED));
- ui_out_text (uiout, "\nProgram terminated with signal ");
+ if (uiout->is_mi_like_p ())
+ uiout->field_string
+ ("reason", async_reason_lookup (EXEC_ASYNC_EXITED_SIGNALLED));
+ uiout->text ("\nProgram terminated with signal ");
annotate_signal_name ();
- ui_out_field_string (uiout, "signal-name",
+ uiout->field_string ("signal-name",
gdb_signal_to_name (siggnal));
annotate_signal_name_end ();
- ui_out_text (uiout, ", ");
+ uiout->text (", ");
annotate_signal_string ();
- ui_out_field_string (uiout, "signal-meaning",
+ uiout->field_string ("signal-meaning",
gdb_signal_to_string (siggnal));
annotate_signal_string_end ();
- ui_out_text (uiout, ".\n");
- ui_out_text (uiout, "The program no longer exists.\n");
+ uiout->text (".\n");
+ uiout->text ("The program no longer exists.\n");
}
void
annotate_exited (exitstatus);
if (exitstatus)
{
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_EXITED));
- ui_out_text (uiout, "[Inferior ");
- ui_out_text (uiout, plongest (inf->num));
- ui_out_text (uiout, " (");
- ui_out_text (uiout, pidstr);
- ui_out_text (uiout, ") exited with code ");
- ui_out_field_fmt (uiout, "exit-code", "0%o", (unsigned int) exitstatus);
- ui_out_text (uiout, "]\n");
+ if (uiout->is_mi_like_p ())
+ uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_EXITED));
+ uiout->text ("[Inferior ");
+ uiout->text (plongest (inf->num));
+ uiout->text (" (");
+ uiout->text (pidstr);
+ uiout->text (") exited with code ");
+ uiout->field_fmt ("exit-code", "0%o", (unsigned int) exitstatus);
+ uiout->text ("]\n");
}
else
{
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason", async_reason_lookup (EXEC_ASYNC_EXITED_NORMALLY));
- ui_out_text (uiout, "[Inferior ");
- ui_out_text (uiout, plongest (inf->num));
- ui_out_text (uiout, " (");
- ui_out_text (uiout, pidstr);
- ui_out_text (uiout, ") exited normally]\n");
+ if (uiout->is_mi_like_p ())
+ uiout->field_string
+ ("reason", async_reason_lookup (EXEC_ASYNC_EXITED_NORMALLY));
+ uiout->text ("[Inferior ");
+ uiout->text (plongest (inf->num));
+ uiout->text (" (");
+ uiout->text (pidstr);
+ uiout->text (") exited normally]\n");
}
}
annotate_signal ();
- if (ui_out_is_mi_like_p (uiout))
+ if (uiout->is_mi_like_p ())
;
else if (show_thread_that_caused_stop ())
{
const char *name;
- ui_out_text (uiout, "\nThread ");
- ui_out_field_fmt (uiout, "thread-id", "%s", print_thread_id (thr));
+ uiout->text ("\nThread ");
+ uiout->field_fmt ("thread-id", "%s", print_thread_id (thr));
name = thr->name != NULL ? thr->name : target_thread_name (thr);
if (name != NULL)
{
- ui_out_text (uiout, " \"");
- ui_out_field_fmt (uiout, "name", "%s", name);
- ui_out_text (uiout, "\"");
+ uiout->text (" \"");
+ uiout->field_fmt ("name", "%s", name);
+ uiout->text ("\"");
}
}
else
- ui_out_text (uiout, "\nProgram");
+ uiout->text ("\nProgram");
- if (siggnal == GDB_SIGNAL_0 && !ui_out_is_mi_like_p (uiout))
- ui_out_text (uiout, " stopped");
+ if (siggnal == GDB_SIGNAL_0 && !uiout->is_mi_like_p ())
+ uiout->text (" stopped");
else
{
- ui_out_text (uiout, " received signal ");
+ uiout->text (" received signal ");
annotate_signal_name ();
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason", async_reason_lookup (EXEC_ASYNC_SIGNAL_RECEIVED));
- ui_out_field_string (uiout, "signal-name",
- gdb_signal_to_name (siggnal));
+ if (uiout->is_mi_like_p ())
+ uiout->field_string
+ ("reason", async_reason_lookup (EXEC_ASYNC_SIGNAL_RECEIVED));
+ uiout->field_string ("signal-name", gdb_signal_to_name (siggnal));
annotate_signal_name_end ();
- ui_out_text (uiout, ", ");
+ uiout->text (", ");
annotate_signal_string ();
- ui_out_field_string (uiout, "signal-meaning",
- gdb_signal_to_string (siggnal));
+ uiout->field_string ("signal-meaning", gdb_signal_to_string (siggnal));
if (siggnal == GDB_SIGNAL_SEGV)
handle_segmentation_fault (uiout);
annotate_signal_string_end ();
}
- ui_out_text (uiout, ".\n");
+ uiout->text (".\n");
}
void
print_no_history_reason (struct ui_out *uiout)
{
- ui_out_text (uiout, "\nNo more reverse-execution history.\n");
+ uiout->text ("\nNo more reverse-execution history.\n");
}
/* Print current location without a level number, if we have changed