/* Target-struct-independent code to start (run) and stop an inferior
process.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free
Software Foundation, Inc.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
#include "gdb_string.h"
#include "value.h"
#include "observer.h"
#include "language.h"
+#include "solib.h"
+#include "main.h"
+
#include "gdb_assert.h"
+#include "mi/mi-common.h"
/* Prototypes for local functions */
no line number information. The normal behavior is that we step
over such function. */
int step_stop_if_no_debug = 0;
+static void
+show_step_stop_if_no_debug (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Mode of the step operation is %s.\n"), value);
+}
/* In asynchronous mode, but simulating synchronous execution. */
static int may_follow_exec = MAY_FOLLOW_EXEC;
static int debug_infrun = 0;
+static void
+show_debug_infrun (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Inferior debugging is %s.\n"), value);
+}
/* If the program uses ELF-style shared libraries, then calls to
functions in shared libraries go through stubs, which live in a
signalling an error, which will obscure the change in the
inferior's state. */
-#ifndef IN_SOLIB_DYNSYM_RESOLVE_CODE
-#define IN_SOLIB_DYNSYM_RESOLVE_CODE(pc) 0
-#endif
-
/* This function returns TRUE if pc is the address of an instruction
that lies within the dynamic linker (such as the event hook, or the
dld itself).
static int trap_expected;
-#ifdef SOLIB_ADD
/* Nonzero if we want to give control to the user when we're notified
of shared library events by the dynamic linker. */
static int stop_on_solib_events;
-#endif
+static void
+show_stop_on_solib_events (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Stopping for shared library events is %s.\n"),
+ value);
+}
/* Nonzero means expecting a trace trap
and should stop the inferior and return silently when it happens. */
};
static const char *follow_fork_mode_string = follow_fork_mode_parent;
+static void
+show_follow_fork_mode_string (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Debugger response to a program call of fork or vfork is \"%s\".\n"),
+ value);
+}
\f
static int
step_range_end = 0;
/* What is this a.out's name? */
- printf_unfiltered ("Executing new program: %s\n", execd_pathname);
+ printf_unfiltered (_("Executing new program: %s\n"), execd_pathname);
/* We've followed the inferior through an exec. Therefore, the
inferior has essentially been killed & reborn. */
#endif
#ifdef SOLIB_CREATE_INFERIOR_HOOK
SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
+#else
+ solib_create_inferior_hook ();
#endif
/* Reinsert all breakpoints. (Those which were symbolic have
static const char schedlock_off[] = "off";
static const char schedlock_on[] = "on";
static const char schedlock_step[] = "step";
-static const char *scheduler_mode = schedlock_off;
static const char *scheduler_enums[] = {
schedlock_off,
schedlock_on,
schedlock_step,
NULL
};
+static const char *scheduler_mode = schedlock_off;
+static void
+show_scheduler_mode (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Mode for locking scheduler during execution is \"%s\".\n"),
+ value);
+}
static void
set_schedlock_func (char *args, int from_tty, struct cmd_list_element *c)
{
- /* NOTE: cagney/2002-03-17: The deprecated_add_show_from_set()
- function clones the set command passed as a parameter. The clone
- operation will include (BUG?) any ``set'' command callback, if
- present. Commands like ``info set'' call all the ``show''
- command callbacks. Unfortunately, for ``show'' commands cloned
- from ``set'', this includes callbacks belonging to ``set''
- commands. Making this worse, this only occures if
- deprecated_add_show_from_set() is called after add_cmd_sfunc()
- (BUG?). */
- if (cmd_type (c) == set_cmd)
- if (!target_can_lock_scheduler)
- {
- scheduler_mode = schedlock_off;
- error (_("Target '%s' cannot support this command."), target_shortname);
- }
+ if (!target_can_lock_scheduler)
+ {
+ scheduler_mode = schedlock_off;
+ error (_("Target '%s' cannot support this command."), target_shortname);
+ }
}
void
init_execution_control_state (struct execution_control_state *ecs)
{
- /* ecs->another_trap? */
+ ecs->another_trap = 0;
ecs->random_signal = 0;
ecs->step_after_step_resume_breakpoint = 0;
ecs->handling_longjmp = 0; /* FIXME */
*status = target_last_waitstatus;
}
+void
+nullify_last_target_wait_ptid (void)
+{
+ target_last_wait_ptid = minus_one_ptid;
+}
+
/* Switch thread contexts, maintaining "infrun state". */
static void
/* When using hardware single-step, a SIGTRAP is reported for
both a completed single-step and a software breakpoint. Need
to differentiate between the two as the latter needs
- adjusting but the former does not. */
- if (currently_stepping (ecs))
+ adjusting but the former does not.
+
+ When the thread to be examined does not match the current thread
+ context we can't use currently_stepping, so assume no
+ single-stepping in this case. */
+ if (ptid_equal (ecs->ptid, inferior_ptid) && currently_stepping (ecs))
{
if (prev_pc == breakpoint_pc
&& software_breakpoint_inserted_here_p (breakpoint_pc))
void
handle_inferior_event (struct execution_control_state *ecs)
{
- /* NOTE: cagney/2003-03-28: If you're looking at this code and
- thinking that the variable stepped_after_stopped_by_watchpoint
- isn't used, then you're wrong! The macro STOPPED_BY_WATCHPOINT,
- defined in the file "config/pa/nm-hppah.h", accesses the variable
- indirectly. Mutter something rude about the HP merge. */
+ /* NOTE: bje/2005-05-02: If you're looking at this code and thinking
+ that the variable stepped_after_stopped_by_watchpoint isn't used,
+ then you're wrong! See remote.c:remote_stopped_data_address. */
+
int sw_single_step_trap_p = 0;
int stopped_by_watchpoint = -1; /* Mark as unknown. */
break;
default:
- internal_error (__FILE__, __LINE__, "bad switch");
+ internal_error (__FILE__, __LINE__, _("bad switch"));
}
ecs->infwait_state = infwait_normal_state;
case BPSTAT_WHAT_CHECK_SHLIBS:
case BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK:
-#ifdef SOLIB_ADD
{
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: BPSTATE_WHAT_CHECK_SHLIBS\n");
exec/process stratum, instead relying on the target stack
to propagate relevant changes (stop, section table
changed, ...) up to other layers. */
+#ifdef SOLIB_ADD
SOLIB_ADD (NULL, 0, ¤t_target, auto_solib_add);
+#else
+ solib_add (NULL, 0, ¤t_target, auto_solib_add);
+#endif
target_terminal_inferior ();
/* Try to reenable shared library breakpoints, additional
break;
}
}
-#endif
break;
case BPSTAT_WHAT_LAST:
until we exit the run time loader code and reach the callee's
address. */
if (step_over_calls == STEP_OVER_UNDEBUGGABLE
- && IN_SOLIB_DYNSYM_RESOLVE_CODE (stop_pc))
+#ifdef IN_SOLIB_DYNSYM_RESOLVE_CODE
+ && IN_SOLIB_DYNSYM_RESOLVE_CODE (stop_pc)
+#else
+ && in_solib_dynsym_resolve_code (stop_pc)
+#endif
+ )
{
CORE_ADDR pc_after_resolver =
gdbarch_skip_solib_resolver (current_gdbarch, stop_pc);
if (real_stop_pc != 0)
ecs->stop_func_start = real_stop_pc;
- if (IN_SOLIB_DYNSYM_RESOLVE_CODE (ecs->stop_func_start))
+ if (
+#ifdef IN_SOLIB_DYNSYM_RESOLVE_CODE
+ IN_SOLIB_DYNSYM_RESOLVE_CODE (ecs->stop_func_start)
+#else
+ in_solib_dynsym_resolve_code (ecs->stop_func_start)
+#endif
+)
{
struct symtab_and_line sr_sal;
init_sal (&sr_sal);
}
}
+ ecs->sal = find_pc_line (stop_pc, 0);
+
/* NOTE: tausq/2004-05-24: This if block used to be done before all
the trampoline processing logic, however, there are some trampolines
that have no names, so we should do trampoline handling first. */
if (step_over_calls == STEP_OVER_UNDEBUGGABLE
- && ecs->stop_func_name == NULL)
+ && ecs->stop_func_name == NULL
+ && ecs->sal.line == 0)
{
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: stepped into undebuggable function\n");
/* The inferior just stepped into, or returned to, an
- undebuggable function (where there is no symbol, not even a
- minimal symbol, corresponding to the address where the
+ undebuggable function (where there is no debugging information
+ and no line number corresponding to the address where the
inferior stopped). Since we want to skip this kind of code,
we keep going until the inferior returns from this
function. */
return;
}
- ecs->sal = find_pc_line (stop_pc, 0);
-
if (ecs->sal.line == 0)
{
/* We have no line number information. That means to stop
operation for n > 1 */
if (!step_multi || !stop_step)
if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "reason", "end-stepping-range");
+ ui_out_field_string
+ (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_END_STEPPING_RANGE));
break;
case BREAKPOINT_HIT:
/* We found a breakpoint. */
/* The inferior was terminated by a signal. */
annotate_signalled ();
if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "reason", "exited-signalled");
+ ui_out_field_string
+ (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_EXITED_SIGNALLED));
ui_out_text (uiout, "\nProgram terminated with signal ");
annotate_signal_name ();
ui_out_field_string (uiout, "signal-name",
if (stop_info)
{
if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "reason", "exited");
+ ui_out_field_string (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_EXITED));
ui_out_text (uiout, "\nProgram exited with code ");
ui_out_field_fmt (uiout, "exit-code", "0%o",
(unsigned int) stop_info);
else
{
if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "reason", "exited-normally");
+ ui_out_field_string
+ (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_EXITED_NORMALLY));
ui_out_text (uiout, "\nProgram exited normally.\n");
}
+ /* Support the --return-child-result option. */
+ return_child_result_value = stop_info;
break;
case SIGNAL_RECEIVED:
/* Signal received. The signal table tells us to print about
ui_out_text (uiout, "\nProgram received signal ");
annotate_signal_name ();
if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "reason", "signal-received");
+ ui_out_field_string
+ (uiout, "reason", async_reason_lookup (EXEC_ASYNC_SIGNAL_RECEIVED));
ui_out_field_string (uiout, "signal-name",
target_signal_to_name (stop_info));
annotate_signal_name_end ();
break;
default:
internal_error (__FILE__, __LINE__,
- "print_stop_reason: unrecognized enum value");
+ _("print_stop_reason: unrecognized enum value"));
break;
}
}
&& last.kind != TARGET_WAITKIND_EXITED)
{
target_terminal_ours_for_output ();
- printf_filtered ("[Switching to %s]\n",
+ printf_filtered (_("[Switching to %s]\n"),
target_pid_or_tid_to_str (inferior_ptid));
previous_inferior_ptid = inferior_ptid;
}
if (remove_breakpoints ())
{
target_terminal_ours_for_output ();
- printf_filtered ("Cannot remove breakpoints because ");
- printf_filtered ("program is no longer writable.\n");
- printf_filtered ("It might be running in another process.\n");
- printf_filtered ("Further execution is probably impossible.\n");
+ printf_filtered (_("\
+Cannot remove breakpoints because program is no longer writable.\n\
+It might be running in another process.\n\
+Further execution is probably impossible.\n"));
}
}
breakpoints_inserted = 0;
target_terminal_ours ();
+ /* Set the current source location. This will also happen if we
+ display the frame below, but the current SAL will be incorrect
+ during a user hook-stop function. */
+ if (target_has_stack && !stop_stack_dummy)
+ set_current_sal_from_frame (get_current_frame (), 1);
+
/* Look up the hook_stop and run it (CLI internally handles problem
of stop_command's pre-hook not existing). */
if (stop_command)
do_frame_printing = 0;
break;
default:
- internal_error (__FILE__, __LINE__, "Unknown value.");
+ internal_error (__FILE__, __LINE__, _("Unknown value."));
}
/* For mi, have the same behavior every time we stop:
print everything but the source line. */
static void
sig_print_header (void)
{
- printf_filtered ("\
-Signal Stop\tPrint\tPass to program\tDescription\n");
+ printf_filtered (_("\
+Signal Stop\tPrint\tPass to program\tDescription\n"));
}
static void
if (args == NULL)
{
- error_no_arg ("signal to handle");
+ error_no_arg (_("signal to handle"));
}
/* Allocate and zero an array of flags for which signals to handle. */
}
else
{
- printf_unfiltered ("Not confirmed, unchanged.\n");
+ printf_unfiltered (_("Not confirmed, unchanged.\n"));
gdb_flush (gdb_stdout);
}
}
if (validFlag)
handle_command (argBuf, from_tty);
else
- printf_filtered ("Invalid signal handling flag.\n");
+ printf_filtered (_("Invalid signal handling flag.\n"));
if (argBuf)
xfree (argBuf);
}
sig_print_info (oursig);
}
- printf_filtered ("\nUse the \"handle\" command to change these tables.\n");
+ printf_filtered (_("\nUse the \"handle\" command to change these tables.\n"));
}
\f
struct inferior_status
DEPRECATED_REGISTER_GDBARCH_SWAP (stop_registers);
deprecated_register_gdbarch_swap (NULL, 0, build_infrun);
- add_info ("signals", signals_info,
- "What debugger does when program gets various signals.\n\
-Specify a signal as argument to print info on that signal only.");
+ add_info ("signals", signals_info, _("\
+What debugger does when program gets various signals.\n\
+Specify a signal as argument to print info on that signal only."));
add_info_alias ("handle", "signals", 0);
- add_com ("handle", class_run, handle_command,
- concat ("Specify how to handle a signal.\n\
+ add_com ("handle", class_run, handle_command, _("\
+Specify how to handle a signal.\n\
Args are signals and actions to apply to those signals.\n\
Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\
from 1-15 are allowed for compatibility with old versions of GDB.\n\
Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\
The special arg \"all\" is recognized to mean all signals except those\n\
-used by the debugger, typically SIGTRAP and SIGINT.\n", "Recognized actions include \"stop\", \"nostop\", \"print\", \"noprint\",\n\
+used by the debugger, typically SIGTRAP and SIGINT.\n\
+Recognized actions include \"stop\", \"nostop\", \"print\", \"noprint\",\n\
\"pass\", \"nopass\", \"ignore\", or \"noignore\".\n\
Stop means reenter debugger if this signal happens (implies print).\n\
Print means print a message if this signal happens.\n\
Pass means let program see this signal; otherwise program doesn't know.\n\
Ignore is a synonym for nopass and noignore is a synonym for pass.\n\
-Pass and Stop may be combined.", NULL));
+Pass and Stop may be combined."));
if (xdb_commands)
{
- add_com ("lz", class_info, signals_info,
- "What debugger does when program gets various signals.\n\
-Specify a signal as argument to print info on that signal only.");
- add_com ("z", class_run, xdb_handle_command,
- concat ("Specify how to handle a signal.\n\
+ add_com ("lz", class_info, signals_info, _("\
+What debugger does when program gets various signals.\n\
+Specify a signal as argument to print info on that signal only."));
+ add_com ("z", class_run, xdb_handle_command, _("\
+Specify how to handle a signal.\n\
Args are signals and actions to apply to those signals.\n\
Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\
from 1-15 are allowed for compatibility with old versions of GDB.\n\
Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\
The special arg \"all\" is recognized to mean all signals except those\n\
-used by the debugger, typically SIGTRAP and SIGINT.\n", "Recognized actions include \"s\" (toggles between stop and nostop), \n\
+used by the debugger, typically SIGTRAP and SIGINT.\n\
+Recognized actions include \"s\" (toggles between stop and nostop), \n\
\"r\" (toggles between print and noprint), \"i\" (toggles between pass and \
nopass), \"Q\" (noprint)\n\
Stop means reenter debugger if this signal happens (implies print).\n\
Print means print a message if this signal happens.\n\
Pass means let program see this signal; otherwise program doesn't know.\n\
Ignore is a synonym for nopass and noignore is a synonym for pass.\n\
-Pass and Stop may be combined.", NULL));
+Pass and Stop may be combined."));
}
if (!dbx_commands)
- stop_command =
- add_cmd ("stop", class_obscure, not_just_help_class_command,
- "There is no `stop' command, but you can set a hook on `stop'.\n\
+ stop_command = add_cmd ("stop", class_obscure,
+ not_just_help_class_command, _("\
+There is no `stop' command, but you can set a hook on `stop'.\n\
This allows you to set a list of commands to be run each time execution\n\
-of the program stops.", &cmdlist);
+of the program stops."), &cmdlist);
- add_set_cmd ("infrun", class_maintenance, var_zinteger,
- &debug_infrun, "Set inferior debugging.\n\
-When non-zero, inferior specific debugging is enabled.", &setdebuglist);
+ add_setshow_zinteger_cmd ("infrun", class_maintenance, &debug_infrun, _("\
+Set inferior debugging."), _("\
+Show inferior debugging."), _("\
+When non-zero, inferior specific debugging is enabled."),
+ NULL,
+ show_debug_infrun,
+ &setdebuglist, &showdebuglist);
numsigs = (int) TARGET_SIGNAL_LAST;
signal_stop = (unsigned char *) xmalloc (sizeof (signal_stop[0]) * numsigs);
signal_stop[TARGET_SIGNAL_CANCEL] = 0;
signal_print[TARGET_SIGNAL_CANCEL] = 0;
-#ifdef SOLIB_ADD
- deprecated_add_show_from_set
- (add_set_cmd ("stop-on-solib-events", class_support, var_zinteger,
- (char *) &stop_on_solib_events,
- "Set stopping for shared library events.\n\
+ add_setshow_zinteger_cmd ("stop-on-solib-events", class_support,
+ &stop_on_solib_events, _("\
+Set stopping for shared library events."), _("\
+Show stopping for shared library events."), _("\
If nonzero, gdb will give control to the user when the dynamic linker\n\
notifies gdb of shared library events. The most common event of interest\n\
-to the user would be loading/unloading of a new library.\n",
- &setlist),
- &showlist);
-#endif
-
- c = add_set_enum_cmd ("follow-fork-mode",
- class_run,
- follow_fork_mode_kind_names, &follow_fork_mode_string,
- "Set debugger response to a program call of fork \
-or vfork.\n\
+to the user would be loading/unloading of a new library."),
+ NULL,
+ show_stop_on_solib_events,
+ &setlist, &showlist);
+
+ add_setshow_enum_cmd ("follow-fork-mode", class_run,
+ follow_fork_mode_kind_names,
+ &follow_fork_mode_string, _("\
+Set debugger response to a program call of fork or vfork."), _("\
+Show debugger response to a program call of fork or vfork."), _("\
A fork or vfork creates a new process. follow-fork-mode can be:\n\
parent - the original process is debugged after a fork\n\
child - the new process is debugged after a fork\n\
The unfollowed process will continue to run.\n\
-By default, the debugger will follow the parent process.", &setlist);
- deprecated_add_show_from_set (c, &showlist);
-
- c = add_set_enum_cmd ("scheduler-locking", class_run,
- scheduler_enums, /* array of string names */
- &scheduler_mode, /* current mode */
- "Set mode for locking scheduler during execution.\n\
+By default, the debugger will follow the parent process."),
+ NULL,
+ show_follow_fork_mode_string,
+ &setlist, &showlist);
+
+ add_setshow_enum_cmd ("scheduler-locking", class_run,
+ scheduler_enums, &scheduler_mode, _("\
+Set mode for locking scheduler during execution."), _("\
+Show mode for locking scheduler during execution."), _("\
off == no locking (threads may preempt at any time)\n\
on == full locking (no thread except the current thread may run)\n\
step == scheduler locked during every single-step operation.\n\
In this mode, no other thread may run during a step command.\n\
- Other threads may run while stepping over a function call ('next').",
- &setlist);
-
- set_cmd_sfunc (c, set_schedlock_func); /* traps on target vector */
- deprecated_add_show_from_set (c, &showlist);
-
- c = add_set_cmd ("step-mode", class_run,
- var_boolean, (char *) &step_stop_if_no_debug,
- "Set mode of the step operation. When set, doing a step over a\n\
-function without debug line information will stop at the first\n\
-instruction of that function. Otherwise, the function is skipped and\n\
-the step command stops at a different source line.", &setlist);
- deprecated_add_show_from_set (c, &showlist);
+ Other threads may run while stepping over a function call ('next')."),
+ set_schedlock_func, /* traps on target vector */
+ show_scheduler_mode,
+ &setlist, &showlist);
+
+ add_setshow_boolean_cmd ("step-mode", class_run, &step_stop_if_no_debug, _("\
+Set mode of the step operation."), _("\
+Show mode of the step operation."), _("\
+When set, doing a step over a function without debug line information\n\
+will stop at the first instruction of that function. Otherwise, the\n\
+function is skipped and the step command stops at a different source line."),
+ NULL,
+ show_step_stop_if_no_debug,
+ &setlist, &showlist);
/* ptid initializations */
null_ptid = ptid_build (0, 0, 0);