📄 infcmd.c
字号:
/* Memory-access and commands for "inferior" (child) process, for GDB. Copyright 1986, 1987, 1988, 1989, 1991, 1992 Free Software Foundation, Inc.This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "defs.h"#include <signal.h>#include <sys/param.h>#include <string.h>#include "symtab.h"#include "gdbtypes.h"#include "frame.h"#include "inferior.h"#include "environ.h"#include "value.h"#include "gdbcmd.h"#include "gdbcore.h"#include "target.h"static voidcontinue_command PARAMS ((char *, int));static voiduntil_next_command PARAMS ((int));static void until_command PARAMS ((char *, int));static voidpath_info PARAMS ((char *, int));static voidpath_command PARAMS ((char *, int));static voidunset_command PARAMS ((char *, int));static voidfloat_info PARAMS ((char *, int));static voiddetach_command PARAMS ((char *, int));static voidnofp_registers_info PARAMS ((char *, int));static voidall_registers_info PARAMS ((char *, int));static voidregisters_info PARAMS ((char *, int));static voiddo_registers_info PARAMS ((int, int));static voidunset_environment_command PARAMS ((char *, int));static voidset_environment_command PARAMS ((char *, int));static voidenvironment_info PARAMS ((char *, int));static voidprogram_info PARAMS ((char *, int));static voidfinish_command PARAMS ((char *, int));static voidsignal_command PARAMS ((char *, int));static voidjump_command PARAMS ((char *, int));static voidstep_1 PARAMS ((int, int, char *));static voidnexti_command PARAMS ((char *, int));static voidstepi_command PARAMS ((char *, int));static voidnext_command PARAMS ((char *, int));static voidstep_command PARAMS ((char *, int));static voidrun_command PARAMS ((char *, int));#define ERROR_NO_INFERIOR \ if (!target_has_execution) error ("The program is not being run.");/* String containing arguments to give to the program, separated by spaces. Empty string (pointer to '\0') means no args. */static char *inferior_args;/* File name for default use for standard in/out in the inferior. */char *inferior_io_terminal;/* Pid of our debugged inferior, or 0 if no inferior now. Since various parts of infrun.c test this to see whether there is a program being debugged it should be nonzero (currently 3 is used) for remote debugging. */int inferior_pid;/* Last signal that the inferior received (why it stopped). */int stop_signal;/* Address at which inferior stopped. */CORE_ADDR stop_pc;/* Stack frame when program stopped. */FRAME_ADDR stop_frame_address;/* Chain containing status of breakpoint(s) that we have stopped at. */bpstat stop_bpstat;/* Flag indicating that a command has proceeded the inferior past the current breakpoint. */int breakpoint_proceeded;/* Nonzero if stopped due to a step command. */int stop_step;/* Nonzero if stopped due to completion of a stack dummy routine. */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. */CORE_ADDR step_range_start; /* Inclusive */CORE_ADDR step_range_end; /* Exclusive *//* Stack frame address as of when stepping command was issued. 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. */FRAME_ADDR step_frame_address;/* 1 means step over all subroutine calls. -1 means step over calls to undebuggable functions. */int step_over_calls;/* If stepping, nonzero means step count is > 1 so don't print frame next time inferior stops if it stops due to stepping. */int step_multi;/* Environment to use for running inferior, in format described in environ.h. */struct environ *inferior_environ;/* ARGSUSED */voidtty_command (file, from_tty) char *file; int from_tty;{ if (file == 0) error_no_arg ("terminal name for running target process"); inferior_io_terminal = savestring (file, strlen (file));}static voidrun_command (args, from_tty) char *args; int from_tty;{ char *exec_file; dont_repeat (); if (inferior_pid) { extern int inhibit_confirm; if (!(inhibit_confirm || query ("The program being debugged has been started already.\n\Start it from the beginning? "))) error ("Program not restarted."); target_kill (); } exec_file = (char *) get_exec_file (0); /* The exec file is re-read every time we do a generic_mourn_inferior, so we just have to worry about the symbol file. */ reread_symbols (); if (args) { char *cmd; cmd = concat ("set args ", args, NULL); make_cleanup (free, cmd); execute_command (cmd, from_tty); } if (from_tty) { printf_filtered ("Starting program: %s %s\n", exec_file? exec_file: "", inferior_args); fflush (stdout); } target_create_inferior (exec_file, inferior_args, environ_vector (inferior_environ));}static voidcontinue_command (proc_count_exp, from_tty) char *proc_count_exp; int from_tty;{ ERROR_NO_INFERIOR; /* If have argument, set proceed count of breakpoint we stopped at. */ if (proc_count_exp != NULL) { bpstat bs = stop_bpstat; int num = bpstat_num (&bs); if (num == 0 && from_tty) { printf_filtered ("Not stopped at any breakpoint; argument ignored.\n"); } while (num != 0) { set_ignore_count (num, parse_and_eval_address (proc_count_exp) - 1, from_tty); /* set_ignore_count prints a message ending with a period. So print two spaces before "Continuing.". */ if (from_tty) printf_filtered (" "); num = bpstat_num (&bs); } } if (from_tty) printf_filtered ("Continuing.\n"); clear_proceed_status (); proceed ((CORE_ADDR) -1, -1, 0);}/* Step until outside of current statement. *//* ARGSUSED */static voidstep_command (count_string, from_tty) char *count_string; int from_tty;{ step_1 (0, 0, count_string);}/* Likewise, but skip over subroutine calls as if single instructions. *//* ARGSUSED */static voidnext_command (count_string, from_tty) char *count_string; int from_tty;{ step_1 (1, 0, count_string);}/* Likewise, but step only one instruction. *//* ARGSUSED */static voidstepi_command (count_string, from_tty) char *count_string; int from_tty;{ step_1 (0, 1, count_string);}/* ARGSUSED */static voidnexti_command (count_string, from_tty) char *count_string; int from_tty;{ step_1 (1, 1, count_string);}static voidstep_1 (skip_subroutines, single_inst, count_string) int skip_subroutines; int single_inst; char *count_string;{ register int count = 1; FRAME fr; struct cleanup *cleanups = 0; ERROR_NO_INFERIOR; count = count_string ? parse_and_eval_address (count_string) : 1; if (!single_inst || skip_subroutines) /* leave si command alone */ { enable_longjmp_breakpoint(); cleanups = make_cleanup(disable_longjmp_breakpoint, 0); } for (; count > 0; count--) { clear_proceed_status (); fr = get_current_frame (); if (!fr) /* Avoid coredump here. Why tho? */ error ("No current frame"); step_frame_address = FRAME_FP (fr); if (! single_inst) { find_pc_line_pc_range (stop_pc, &step_range_start, &step_range_end); if (step_range_end == 0) { struct minimal_symbol *msymbol; msymbol = lookup_minimal_symbol_by_pc (stop_pc); target_terminal_ours (); printf_filtered ("Current function has no line number information.\n"); fflush (stdout); /* No info or after _etext ("Can't happen") */ if (msymbol == NULL || (msymbol + 1) -> name == NULL) error ("No data available on pc function."); printf_filtered ("Single stepping until function exit.\n"); fflush (stdout); step_range_start = msymbol -> address; step_range_end = (msymbol + 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. */ step_range_start = step_range_end = 1; if (!skip_subroutines) step_over_calls = 0; } if (skip_subroutines) step_over_calls = 1; step_multi = (count > 1); proceed ((CORE_ADDR) -1, -1, 1); if (! stop_step) break;#if defined (SHIFT_INST_REGS) write_register (NNPC_REGNUM, read_register (NPC_REGNUM)); write_register (NPC_REGNUM, read_register (PC_REGNUM));#endif } if (!single_inst || skip_subroutines) do_cleanups(cleanups);}/* Continue program at specified address. */static voidjump_command (arg, from_tty) char *arg; int from_tty;{ register CORE_ADDR addr; struct symtabs_and_lines sals; struct symtab_and_line sal; struct symbol *fn; struct symbol *sfn; char *fname; struct cleanup *back_to; ERROR_NO_INFERIOR; if (!arg) error_no_arg ("starting address"); sals = decode_line_spec_1 (arg, 1); if (sals.nelts != 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -