aboutsummaryrefslogtreecommitdiff
path: root/gdb/infcmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/infcmd.c')
-rw-r--r--gdb/infcmd.c268
1 files changed, 203 insertions, 65 deletions
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 4f7230c..086e1f3 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -19,9 +19,8 @@ anyone else from sharing it farther. Help stamp out software hoarding!
*/
#include "defs.h"
-#include "initialize.h"
-#include "symtab.h"
#include "param.h"
+#include "symtab.h"
#include "frame.h"
#include "inferior.h"
#include "environ.h"
@@ -59,7 +58,7 @@ CORE_ADDR stop_pc;
/* Stack frame when program stopped. */
-FRAME stop_frame;
+FRAME_ADDR stop_frame_address;
/* Number of breakpoint it stopped at, or 0 if none. */
@@ -73,6 +72,11 @@ int stop_step;
int stop_stack_dummy;
+/* Nonzero if stopped due to a random (unexpected) signal in inferior
+ process. */
+
+int stopped_by_random_signal;
+
/* Range to single step within.
If this is nonzero, respond to a single-step signal
by continuing to step if the pc is in this range. */
@@ -84,7 +88,7 @@ CORE_ADDR step_range_end; /* Exclusive */
This is how we know when we step into a subroutine call,
and how to set the frame for the breakpoint used to step out. */
-CORE_ADDR step_frame;
+FRAME_ADDR step_frame_address;
/* 1 means step over all subroutine calls.
-1 means step over calls to undebuggable functions. */
@@ -105,7 +109,6 @@ struct environ *inferior_environ;
CORE_ADDR read_pc ();
struct command_line *get_breakpoint_commands ();
-START_FILE
int
have_inferior_p ()
@@ -150,11 +153,11 @@ run_command (args, from_tty)
if (inferior_pid)
{
- if (query ("The program being debugged has been started already.\n\
+ if (
+ !query ("The program being debugged has been started already.\n\
Start it from the beginning? "))
- kill_inferior ();
- else
- error ("Program already started.");
+ error ("Program not restarted.");
+ kill_inferior ();
}
if (remote_debugging)
@@ -200,7 +203,7 @@ cont_command (proc_count_exp, from_tty)
/* If have argument, set proceed count of breakpoint we stopped at. */
- if (stop_breakpoint && proc_count_exp)
+ if (stop_breakpoint > 0 && proc_count_exp)
{
set_ignore_count (stop_breakpoint,
parse_and_eval_address (proc_count_exp) - 1,
@@ -261,21 +264,36 @@ step_1 (skip_subroutines, single_inst, count_string)
{
clear_proceed_status ();
- step_frame = get_current_frame ();
+ step_frame_address = FRAME_FP (get_current_frame ());
if (! single_inst)
{
find_pc_line_pc_range (stop_pc, &step_range_start, &step_range_end);
if (step_range_end == 0)
{
+ int misc;
+
+ misc = find_pc_misc_function (stop_pc);
terminal_ours ();
- error ("Current function has no line number information.");
+ printf ("Current function has no line number information.\n");
+ fflush (stdout);
+
+ /* No info or after _etext ("Can't happen") */
+ if (misc == -1 || misc == misc_function_count - 1)
+ error ("No data available on pc function.");
+
+ printf ("Single stepping until function exit.\n");
+ fflush (stdout);
+
+ step_range_start = misc_function_vector[misc].address;
+ step_range_end = misc_function_vector[misc + 1].address;
}
}
else
{
/* Say we are stepping, but stop after one insn whatever it does.
- Don't step through subroutine calls even to undebuggable functions. */
+ Don't step through subroutine calls even to undebuggable
+ functions. */
step_range_start = step_range_end = 1;
if (!skip_subroutines)
step_over_calls = 0;
@@ -307,7 +325,7 @@ jump_command (arg, from_tty)
if (!arg)
error_no_arg ("starting address");
- sals = decode_line_spec (arg, 1);
+ sals = decode_line_spec_1 (arg, 1);
if (sals.nelts != 1)
{
error ("Unreasonable jump request");
@@ -393,20 +411,6 @@ run_stack_dummy (addr, buffer)
CORE_ADDR addr;
REGISTER_TYPE *buffer;
{
- int saved_pc_changed = pc_changed;
- int saved_stop_signal = stop_signal;
- int saved_stop_pc = stop_pc;
- int saved_stop_frame = stop_frame;
- int saved_stop_breakpoint = stop_breakpoint;
- int saved_stop_step = stop_step;
- int saved_stop_stack_dummy = stop_stack_dummy;
- FRAME saved_selected_frame;
- int saved_selected_level;
- struct command_line *saved_breakpoint_commands
- = get_breakpoint_commands ();
-
- record_selected_frame (&saved_selected_frame, &saved_selected_level);
-
/* Now proceed, having reached the desired place. */
clear_proceed_status ();
if (stack_dummy_testing & 4)
@@ -419,21 +423,86 @@ run_stack_dummy (addr, buffer)
if (!stop_stack_dummy)
error ("Cannot continue previously requested operation.");
- set_breakpoint_commands (saved_breakpoint_commands);
- select_frame (saved_selected_frame, saved_selected_level);
- stop_signal = saved_stop_signal;
- stop_pc = saved_stop_pc;
- stop_frame = saved_stop_frame;
- stop_breakpoint = saved_stop_breakpoint;
- stop_step = saved_stop_step;
- stop_stack_dummy = saved_stop_stack_dummy;
- pc_changed = saved_pc_changed;
-
/* On return, the stack dummy has been popped already. */
bcopy (stop_registers, buffer, sizeof stop_registers);
}
+/* Proceed until we reach the given line as argument or exit the
+ function. When called with no argument, proceed until we reach a
+ different source line with pc greater than our current one or exit
+ the function. We skip calls in both cases.
+
+ The effect of this command with an argument is identical to setting
+ a momentary breakpoint at the line specified and executing
+ "finish".
+
+ Note that eventually this command should probably be changed so
+ that only source lines are printed out when we hit the breakpoint
+ we set. I'm going to postpone this until after a hopeful rewrite
+ of wait_for_inferior and the proceed status code. -- randy */
+
+void
+until_next_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ FRAME frame;
+ CORE_ADDR pc;
+ struct symbol *func;
+ struct symtab_and_line sal;
+
+ clear_proceed_status ();
+
+ frame = get_current_frame ();
+
+ /* Step until either exited from this function or greater
+ than the current line (if in symbolic section) or pc (if
+ not). */
+
+ pc = read_pc ();
+ func = find_pc_function (pc);
+
+ if (!func)
+ {
+ int misc_func = find_pc_misc_function (pc);
+
+ if (misc_func != -1)
+ error ("Execution is not within a known function.");
+
+ step_range_start = misc_function_vector[misc_func].address;
+ step_range_end = pc;
+ }
+ else
+ {
+ sal = find_pc_line (pc, 0);
+
+ step_range_start = BLOCK_START (SYMBOL_BLOCK_VALUE (func));
+ step_range_end = sal.end;
+ }
+
+ step_over_calls = 1;
+ step_frame_address = FRAME_FP (frame);
+
+ step_multi = 0; /* Only one call to proceed */
+
+ proceed (-1, -1, 1);
+}
+
+void
+until_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ if (!have_inferior_p ())
+ error ("The program is not being run.");
+
+ if (arg)
+ until_break_command (arg, from_tty);
+ else
+ until_next_command (arg, from_tty);
+}
+
/* "finish": Set a temporary breakpoint at the place
the selected frame will return to, then continue. */
@@ -444,8 +513,7 @@ finish_command (arg, from_tty)
{
struct symtab_and_line sal;
register FRAME frame;
- struct frame_info fi;
-
+ struct frame_info *fi;
register struct symbol *function;
if (!have_inferior_p ())
@@ -460,14 +528,14 @@ finish_command (arg, from_tty)
clear_proceed_status ();
fi = get_frame_info (frame);
- sal = find_pc_line (fi.pc, 0);
- sal.pc = fi.pc;
+ sal = find_pc_line (fi->pc, 0);
+ sal.pc = fi->pc;
set_momentary_breakpoint (sal, frame);
/* Find the function we will return from. */
- fi = get_frame_info (fi.next_frame, fi.next_next_frame);
- function = find_pc_function (fi.pc);
+ fi = get_frame_info (selected_frame);
+ function = find_pc_function (fi->pc);
if (from_tty)
{
@@ -481,12 +549,22 @@ finish_command (arg, from_tty)
{
struct type *value_type;
register value val;
+ CORE_ADDR funcaddr;
value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
+ if (!value_type)
+ fatal ("internal: finish_command: function has no target type");
+
if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
return;
- val = value_being_returned (value_type, stop_registers);
+ funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function));
+
+ val = value_being_returned (value_type, stop_registers,
+ using_struct_return (function,
+ funcaddr,
+ value_type));
+
printf ("Value returned is $%d = ", record_latest_value (val));
value_print (val, stdout, 0);
putchar ('\n');
@@ -506,7 +584,7 @@ program_info ()
inferior_pid, stop_pc);
if (stop_step)
printf ("It stopped after being stepped.\n");
- else if (stop_breakpoint)
+ else if (stop_breakpoint > 0)
printf ("It stopped at breakpoint %d.\n", stop_breakpoint);
else if (stop_signal)
printf ("It stopped with signal %d (%s).\n",
@@ -540,30 +618,58 @@ set_environment_command (arg)
char *arg;
{
register char *p, *val, *var;
+ int nullset = 0;
if (arg == 0)
error_no_arg ("environment variable and value");
+ /* Find seperation between variable name and value */
p = (char *) index (arg, '=');
val = (char *) index (arg, ' ');
+
if (p != 0 && val != 0)
- p = arg + min (p - arg, val - arg);
+ {
+ /* We have both a space and an equals. If the space is before the
+ equals and the only thing between the two is more space, use
+ the equals */
+ if (p > val)
+ while (*val == ' ')
+ val++;
+
+ /* Take the smaller of the two. If there was space before the
+ "=", they will be the same right now. */
+ p = arg + min (p - arg, val - arg);
+ }
else if (val != 0 && p == 0)
p = val;
- if (p == 0)
- error ("Space or \"=\" must separate variable name and its value");
- if (p[1] == 0)
- error_no_arg ("value for the variable");
if (p == arg)
error_no_arg ("environment variable to set");
- val = p + 1;
- while (*val == ' ' || *val == '\t') val++;
+ if (p == 0 || p[1] == 0)
+ {
+ nullset = 1;
+ if (p == 0)
+ p = arg + strlen (arg); /* So that savestring below will work */
+ }
+ else
+ {
+ /* Not setting variable value to null */
+ val = p + 1;
+ while (*val == ' ' || *val == '\t')
+ val++;
+ }
+
while (p != arg && (p[-1] == ' ' || p[-1] == '\t')) p--;
var = savestring (arg, p - arg);
- set_in_environ (inferior_environ, var, val);
+ if (nullset)
+ {
+ printf ("Setting environment variable \"%s\" to null value.\n", var);
+ set_in_environ (inferior_environ, var, "");
+ }
+ else
+ set_in_environ (inferior_environ, var, val);
free (var);
}
@@ -579,6 +685,7 @@ unset_environment_command (var)
/* Read an integer from debugged memory, given address and number of bytes. */
+long
read_memory_integer (memaddr, len)
CORE_ADDR memaddr;
int len;
@@ -617,6 +724,7 @@ read_pc ()
return (CORE_ADDR) read_register (PC_REGNUM);
}
+void
write_pc (val)
CORE_ADDR val;
{
@@ -635,6 +743,9 @@ registers_info (addr_exp)
register int i;
int regnum;
+ if (!have_inferior_p () && !have_core_file_p ())
+ error ("No inferior or core file");
+
if (addr_exp)
{
if (*addr_exp >= '0' && *addr_exp <= '9')
@@ -669,7 +780,7 @@ registers_info (addr_exp)
{
printf ("--Type Return to print more--");
fflush (stdout);
- read_line ();
+ gdb_read_line (0, 0);
}
/* Get the data in raw format, then convert also to virtual format. */
@@ -681,7 +792,8 @@ registers_info (addr_exp)
/* If virtual format is floating, print it that way. */
if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT
&& ! INVALID_FLOAT (virtual_buffer, REGISTER_VIRTUAL_SIZE (i)))
- val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, stdout, 0, 1);
+ val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0,
+ stdout, 0, 1);
/* Else if virtual format is too long for printf,
print in hex a byte at a time. */
else if (REGISTER_VIRTUAL_SIZE (i) > sizeof (long))
@@ -824,16 +936,31 @@ detach_command (args, from_tty)
inferior_pid = 0;
}
#endif /* ATTACH_DETACH */
+
+/* ARGUSUED */
+static void
+float_info (addr_exp)
+ char *addr_exp;
+{
+#ifdef FLOAT_INFO
+ FLOAT_INFO;
+#else
+ printf ("No floating point info available for this processor.\n");
+#endif
+}
-static
-initialize ()
+extern struct cmd_list_element *setlist, *deletelist;
+
+void
+_initialize_infcmd ()
{
add_com ("tty", class_run, tty_command,
"Set terminal for future runs of program being debugged.");
- add_com ("set-args", class_run, set_args_command,
+ add_cmd ("args", class_run, set_args_command,
"Specify arguments to give program being debugged when it is started.\n\
-Follow this command with any number of args, to be passed to the program.");
+Follow this command with any number of args, to be passed to the program.",
+ &setlist);
add_info ("environment", environment_info,
"The environment to give the program, or one variable's value.\n\
@@ -841,14 +968,17 @@ With an argument VAR, prints the value of environment variable VAR to\n\
give the program being debugged. With no arguments, prints the entire\n\
environment to be given to the program.");
- add_com ("unset-environment", class_run, unset_environment_command,
+ add_cmd ("environment", class_run, unset_environment_command,
"Cancel environment variable VAR for the program.\n\
-This does not affect the program until the next \"run\" command.");
- add_com ("set-environment", class_run, set_environment_command,
+This does not affect the program until the next \"run\" command.",
+ &deletelist);
+
+ add_cmd ("environment", class_run, set_environment_command,
"Set environment variable value to give the program.\n\
Arguments are VAR VALUE where VAR is variable name and VALUE is value.\n\
VALUES of environment variables are uninterpreted strings.\n\
-This does not affect the program until the next \"run\" command.");
+This does not affect the program until the next \"run\" command.",
+ &setlist);
#ifdef ATTACH_DETACH
add_com ("attach", class_run, attach_command,
@@ -892,6 +1022,12 @@ Argument N means do this N times (or till program stops for another reason).");
Argument N means do this N times (or till program stops for another reason).");
add_com_alias ("s", "step", class_run, 1);
+ add_com ("until", class_run, until_command,
+ "Execute until the program reaches a source line greater than the current\n\
+or a specified line or address or function (same args as break command).\n\
+Execution will also stop upon exit from the current stack frame.");
+ add_com_alias ("u", "until", class_run, 1);
+
add_com ("jump", class_run, jump_command,
"Continue program being debugged at specified line or address.\n\
Give as argument either LINENUM or *ADDR, where ADDR is an expression\n\
@@ -919,9 +1055,11 @@ Register name as argument means describe only that register.");
add_info ("program", program_info,
"Execution status of the program.");
+ add_info ("float", float_info,
+ "Print the status of the floating point unit\n");
+
inferior_args = savestring (" ", 1); /* By default, no args. */
inferior_environ = make_environ ();
init_environ (inferior_environ);
}
-END_FILE