gdb/infcmd.c - gdb
Global variables defined
Data types defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "arch-utils.h"
- #include <signal.h>
- #include "symtab.h"
- #include "gdbtypes.h"
- #include "frame.h"
- #include "inferior.h"
- #include "infrun.h"
- #include "environ.h"
- #include "value.h"
- #include "gdbcmd.h"
- #include "symfile.h"
- #include "gdbcore.h"
- #include "target.h"
- #include "language.h"
- #include "objfiles.h"
- #include "completer.h"
- #include "ui-out.h"
- #include "event-top.h"
- #include "parser-defs.h"
- #include "regcache.h"
- #include "reggroups.h"
- #include "block.h"
- #include "solib.h"
- #include <ctype.h>
- #include "observer.h"
- #include "target-descriptions.h"
- #include "user-regs.h"
- #include "cli/cli-decode.h"
- #include "gdbthread.h"
- #include "valprint.h"
- #include "inline-frame.h"
- #include "tracepoint.h"
- #include "inf-loop.h"
- #include "continuations.h"
- #include "linespec.h"
- #include "cli/cli-utils.h"
- static void nofp_registers_info (char *, int);
- static void print_return_value (struct value *function,
- struct type *value_type);
- static void until_next_command (int);
- static void until_command (char *, int);
- static void path_info (char *, int);
- static void path_command (char *, int);
- static void unset_command (char *, int);
- static void float_info (char *, int);
- static void disconnect_command (char *, int);
- static void unset_environment_command (char *, int);
- static void set_environment_command (char *, int);
- static void environment_info (char *, int);
- static void program_info (char *, int);
- static void finish_command (char *, int);
- static void signal_command (char *, int);
- static void jump_command (char *, int);
- static void step_1 (int, int, char *);
- static void step_once (int skip_subroutines, int single_inst,
- int count, int thread);
- static void next_command (char *, int);
- static void step_command (char *, int);
- static void run_command (char *, int);
- static void run_no_args_command (char *args, int from_tty);
- static void go_command (char *line_no, int from_tty);
- void _initialize_infcmd (void);
- #define ERROR_NO_INFERIOR \
- if (!target_has_execution) error (_("The program is not being run."));
- static char *inferior_args_scratch;
- static char *inferior_io_terminal_scratch;
- ptid_t inferior_ptid;
- CORE_ADDR stop_pc;
- enum stop_stack_kind stop_stack_dummy;
- int stopped_by_random_signal;
- int startup_with_shell = 1;
- void
- set_inferior_io_terminal (const char *terminal_name)
- {
- xfree (current_inferior ()->terminal);
- current_inferior ()->terminal = terminal_name ? xstrdup (terminal_name) : 0;
- }
- const char *
- get_inferior_io_terminal (void)
- {
- return current_inferior ()->terminal;
- }
- static void
- set_inferior_tty_command (char *args, int from_tty,
- struct cmd_list_element *c)
- {
-
- set_inferior_io_terminal (inferior_io_terminal_scratch);
- }
- static void
- show_inferior_tty_command (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
- {
-
- const char *inferior_io_terminal = get_inferior_io_terminal ();
- if (inferior_io_terminal == NULL)
- inferior_io_terminal = "";
- fprintf_filtered (gdb_stdout,
- _("Terminal for future runs of program being debugged "
- "is \"%s\".\n"), inferior_io_terminal);
- }
- char *
- get_inferior_args (void)
- {
- if (current_inferior ()->argc != 0)
- {
- char *n;
- n = construct_inferior_arguments (current_inferior ()->argc,
- current_inferior ()->argv);
- set_inferior_args (n);
- xfree (n);
- }
- if (current_inferior ()->args == NULL)
- current_inferior ()->args = xstrdup ("");
- return current_inferior ()->args;
- }
- void
- set_inferior_args (char *newargs)
- {
- xfree (current_inferior ()->args);
- current_inferior ()->args = newargs ? xstrdup (newargs) : NULL;
- current_inferior ()->argc = 0;
- current_inferior ()->argv = 0;
- }
- void
- set_inferior_args_vector (int argc, char **argv)
- {
- current_inferior ()->argc = argc;
- current_inferior ()->argv = argv;
- }
- static void
- set_args_command (char *args, int from_tty, struct cmd_list_element *c)
- {
-
- set_inferior_args (inferior_args_scratch);
- }
- static void
- show_args_command (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
- {
-
- deprecated_show_value_hack (file, from_tty, c, get_inferior_args ());
- }
- char *
- construct_inferior_arguments (int argc, char **argv)
- {
- char *result;
- if (startup_with_shell)
- {
- #ifdef __MINGW32__
-
- char *special = "\"!&*|[]{}<>?`~^=;, \t\n";
- const char quote = '"';
- #else
-
- char *special = "\"!#$&*()\\|[]{}<>?'`~^; \t\n";
- const char quote = '\'';
- #endif
- int i;
- int length = 0;
- char *out, *cp;
-
- for (i = 0; i < argc; ++i)
- length += 3 * strlen (argv[i]) + 1 + 2 * (argv[i][0] == '\0');
- result = (char *) xmalloc (length);
- out = result;
- for (i = 0; i < argc; ++i)
- {
- if (i > 0)
- *out++ = ' ';
-
- if (argv[i][0] == '\0')
- {
- *out++ = quote;
- *out++ = quote;
- }
- else
- {
- #ifdef __MINGW32__
- int quoted = 0;
- if (strpbrk (argv[i], special))
- {
- quoted = 1;
- *out++ = quote;
- }
- #endif
- for (cp = argv[i]; *cp; ++cp)
- {
- if (*cp == '\n')
- {
-
- *out++ = quote;
- *out++ = '\n';
- *out++ = quote;
- }
- else
- {
- #ifdef __MINGW32__
- if (*cp == quote)
- #else
- if (strchr (special, *cp) != NULL)
- #endif
- *out++ = '\\';
- *out++ = *cp;
- }
- }
- #ifdef __MINGW32__
- if (quoted)
- *out++ = quote;
- #endif
- }
- }
- *out = '\0';
- }
- else
- {
-
- int i;
- int length = 0;
- for (i = 0; i < argc; ++i)
- {
- char *cp = strchr (argv[i], ' ');
- if (cp == NULL)
- cp = strchr (argv[i], '\t');
- if (cp == NULL)
- cp = strchr (argv[i], '\n');
- if (cp != NULL)
- error (_("can't handle command-line "
- "argument containing whitespace"));
- length += strlen (argv[i]) + 1;
- }
- result = (char *) xmalloc (length);
- result[0] = '\0';
- for (i = 0; i < argc; ++i)
- {
- if (i > 0)
- strcat (result, " ");
- strcat (result, argv[i]);
- }
- }
- return result;
- }
- static char *
- strip_bg_char (const char *args, int *bg_char_p)
- {
- const char *p;
- if (args == NULL || *args == '\0')
- {
- *bg_char_p = 0;
- return NULL;
- }
- p = args + strlen (args);
- if (p[-1] == '&')
- {
- p--;
- while (p > args && isspace (p[-1]))
- p--;
- *bg_char_p = 1;
- if (p != args)
- return savestring (args, p - args);
- else
- return NULL;
- }
- *bg_char_p = 0;
- return xstrdup (args);
- }
- void
- post_create_inferior (struct target_ops *target, int from_tty)
- {
- volatile struct gdb_exception ex;
-
- target_terminal_ours ();
-
- target_find_description ();
-
- stop_pc = 0;
- TRY_CATCH (ex, RETURN_MASK_ERROR)
- {
- stop_pc = regcache_read_pc (get_current_regcache ());
- }
- if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
- throw_exception (ex);
- if (exec_bfd)
- {
- const unsigned solib_add_generation
- = current_program_space->solib_add_generation;
-
- solib_create_inferior_hook (from_tty);
- if (current_program_space->solib_add_generation == solib_add_generation)
- {
-
- if (info_verbose)
- warning (_("platform-specific solib_create_inferior_hook did "
- "not load initial shared libraries."));
-
- if (!gdbarch_has_global_solist (target_gdbarch ()))
- solib_add (NULL, 0, target, auto_solib_add);
- }
- }
-
- breakpoint_re_set ();
- observer_notify_inferior_created (target, from_tty);
- }
- static void
- kill_if_already_running (int from_tty)
- {
- if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
- {
-
- target_require_runnable ();
- if (from_tty
- && !query (_("The program being debugged has been started already.\n\
- Start it from the beginning? ")))
- error (_("Program not restarted."));
- target_kill ();
- }
- }
- void
- prepare_execution_command (struct target_ops *target, int background)
- {
-
- if (background && !target->to_can_async_p (target))
- error (_("Asynchronous execution not supported on this target."));
-
- if (!background && target->to_can_async_p (target))
- {
-
- async_disable_stdin ();
- }
- }
- static void
- run_command_1 (char *args, int from_tty, int tbreak_at_main)
- {
- char *exec_file;
- struct cleanup *old_chain;
- ptid_t ptid;
- struct ui_out *uiout = current_uiout;
- struct target_ops *run_target;
- int async_exec;
- struct cleanup *args_chain;
- dont_repeat ();
- kill_if_already_running (from_tty);
- init_wait_for_inferior ();
- clear_breakpoint_hit_counts ();
-
- target_pre_inferior (from_tty);
-
- reopen_exec_file ();
- reread_symbols ();
- args = strip_bg_char (args, &async_exec);
- args_chain = make_cleanup (xfree, args);
-
- run_target = find_run_target ();
- prepare_execution_command (run_target, async_exec);
- if (non_stop && !run_target->to_supports_non_stop (run_target))
- error (_("The target does not support running in non-stop mode."));
-
-
- if (tbreak_at_main)
- tbreak_command (main_name (), 0);
- exec_file = (char *) get_exec_file (0);
-
-
- if (args != NULL)
- set_inferior_args (args);
- if (from_tty)
- {
- ui_out_field_string (uiout, NULL, "Starting program");
- ui_out_text (uiout, ": ");
- if (exec_file)
- ui_out_field_string (uiout, "execfile", exec_file);
- ui_out_spaces (uiout, 1);
-
- ui_out_field_string (uiout, "infargs", get_inferior_args ());
- ui_out_text (uiout, "\n");
- ui_out_flush (uiout);
- }
-
- do_cleanups (args_chain);
-
- run_target->to_create_inferior (run_target, exec_file, get_inferior_args (),
- environ_vector (current_inferior ()->environment),
- from_tty);
-
- run_target = NULL;
-
- if (non_stop)
- ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
- else
- ptid = minus_one_ptid;
- old_chain = make_cleanup (finish_thread_state_cleanup, &ptid);
-
- post_create_inferior (¤t_target, 0);
-
- proceed (regcache_read_pc (get_current_regcache ()), GDB_SIGNAL_0, 0);
-
- discard_cleanups (old_chain);
- }
- static void
- run_command (char *args, int from_tty)
- {
- run_command_1 (args, from_tty, 0);
- }
- static void
- run_no_args_command (char *args, int from_tty)
- {
- set_inferior_args ("");
- }
- static void
- start_command (char *args, int from_tty)
- {
-
- if (!have_minimal_symbols ())
- error (_("No symbol table loaded. Use the \"file\" command."));
-
- run_command_1 (args, from_tty, 1);
- }
- static int
- proceed_thread_callback (struct thread_info *thread, void *arg)
- {
-
- if (!is_stopped (thread->ptid))
- return 0;
- switch_to_thread (thread->ptid);
- clear_proceed_status (0);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
- return 0;
- }
- static void
- ensure_valid_thread (void)
- {
- if (ptid_equal (inferior_ptid, null_ptid)
- || is_exited (inferior_ptid))
- error (_("Cannot execute this command without a live selected thread."));
- }
- static void
- ensure_not_tfind_mode (void)
- {
- if (get_traceframe_number () >= 0)
- error (_("Cannot execute this command while looking at trace frames."));
- }
- static void
- error_is_running (void)
- {
- error (_("Cannot execute this command while "
- "the selected thread is running."));
- }
- static void
- ensure_not_running (void)
- {
- if (is_running (inferior_ptid))
- error_is_running ();
- }
- void
- continue_1 (int all_threads)
- {
- ERROR_NO_INFERIOR;
- ensure_not_tfind_mode ();
- if (non_stop && all_threads)
- {
-
- struct cleanup *old_chain;
-
- old_chain = make_cleanup_restore_current_thread ();
- iterate_over_threads (proceed_thread_callback, NULL);
- if (sync_execution)
- {
-
- target_terminal_inferior ();
- }
-
- do_cleanups (old_chain);
- }
- else
- {
- ensure_valid_thread ();
- ensure_not_running ();
- clear_proceed_status (0);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
- }
- }
- static void
- continue_command (char *args, int from_tty)
- {
- int async_exec;
- int all_threads = 0;
- struct cleanup *args_chain;
- ERROR_NO_INFERIOR;
-
- args = strip_bg_char (args, &async_exec);
- args_chain = make_cleanup (xfree, args);
- prepare_execution_command (¤t_target, async_exec);
- if (args != NULL)
- {
- if (strncmp (args, "-a", sizeof ("-a") - 1) == 0)
- {
- all_threads = 1;
- args += sizeof ("-a") - 1;
- if (*args == '\0')
- args = NULL;
- }
- }
- if (!non_stop && all_threads)
- error (_("`-a' is meaningless in all-stop mode."));
- if (args != NULL && all_threads)
- error (_("Can't resume all threads and specify "
- "proceed count simultaneously."));
-
- if (args != NULL)
- {
- bpstat bs = NULL;
- int num, stat;
- int stopped = 0;
- struct thread_info *tp;
- if (non_stop)
- tp = find_thread_ptid (inferior_ptid);
- else
- {
- ptid_t last_ptid;
- struct target_waitstatus ws;
- get_last_target_status (&last_ptid, &ws);
- tp = find_thread_ptid (last_ptid);
- }
- if (tp != NULL)
- bs = tp->control.stop_bpstat;
- while ((stat = bpstat_num (&bs, &num)) != 0)
- if (stat > 0)
- {
- set_ignore_count (num,
- parse_and_eval_long (args) - 1,
- from_tty);
-
- if (from_tty)
- printf_filtered (" ");
- stopped = 1;
- }
- if (!stopped && from_tty)
- {
- printf_filtered
- ("Not stopped at any breakpoint; argument ignored.\n");
- }
- }
-
- do_cleanups (args_chain);
- if (from_tty)
- printf_filtered (_("Continuing.\n"));
- continue_1 (all_threads);
- }
- static void
- set_step_frame (void)
- {
- struct symtab_and_line sal;
- find_frame_sal (get_current_frame (), &sal);
- set_step_info (get_current_frame (), sal);
- }
- static void
- step_command (char *count_string, int from_tty)
- {
- step_1 (0, 0, count_string);
- }
- static void
- next_command (char *count_string, int from_tty)
- {
- step_1 (1, 0, count_string);
- }
- static void
- stepi_command (char *count_string, int from_tty)
- {
- step_1 (0, 1, count_string);
- }
- static void
- nexti_command (char *count_string, int from_tty)
- {
- step_1 (1, 1, count_string);
- }
- void
- delete_longjmp_breakpoint_cleanup (void *arg)
- {
- int thread = * (int *) arg;
- delete_longjmp_breakpoint (thread);
- }
- static void
- step_1 (int skip_subroutines, int single_inst, char *count_string)
- {
- int count = 1;
- struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
- int async_exec;
- int thread = -1;
- struct cleanup *args_chain;
- ERROR_NO_INFERIOR;
- ensure_not_tfind_mode ();
- ensure_valid_thread ();
- ensure_not_running ();
- count_string = strip_bg_char (count_string, &async_exec);
- args_chain = make_cleanup (xfree, count_string);
- prepare_execution_command (¤t_target, async_exec);
- count = count_string ? parse_and_eval_long (count_string) : 1;
-
- do_cleanups (args_chain);
- if (!single_inst || skip_subroutines)
- {
- struct thread_info *tp = inferior_thread ();
- if (in_thread_list (inferior_ptid))
- thread = pid_to_thread_id (inferior_ptid);
- set_longjmp_breakpoint (tp, get_frame_id (get_current_frame ()));
- make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
- }
-
- if (!target_can_async_p ())
- {
- for (; count > 0; count--)
- {
- step_once (skip_subroutines, single_inst, count, thread);
- if (!target_has_execution)
- break;
- else
- {
- struct thread_info *tp = inferior_thread ();
- if (!tp->control.stop_step || !tp->step_multi)
- {
-
- tp->step_multi = 0;
- break;
- }
- }
- }
- do_cleanups (cleanups);
- }
- else
- {
-
- step_once (skip_subroutines, single_inst, count, thread);
-
- discard_cleanups (cleanups);
- }
- }
- struct step_1_continuation_args
- {
- int count;
- int skip_subroutines;
- int single_inst;
- int thread;
- };
- static void
- step_1_continuation (void *args, int err)
- {
- struct step_1_continuation_args *a = args;
- if (target_has_execution)
- {
- struct thread_info *tp;
- tp = inferior_thread ();
- if (!err
- && tp->step_multi && tp->control.stop_step)
- {
-
- step_once (a->skip_subroutines, a->single_inst,
- a->count - 1, a->thread);
- return;
- }
- tp->step_multi = 0;
- }
-
- if (!a->single_inst || a->skip_subroutines)
- delete_longjmp_breakpoint (a->thread);
- }
- static void
- step_once (int skip_subroutines, int single_inst, int count, int thread)
- {
- struct frame_info *frame = get_current_frame ();
- if (count > 0)
- {
-
- struct thread_info *tp = inferior_thread ();
- clear_proceed_status (!skip_subroutines);
- set_step_frame ();
- if (!single_inst)
- {
- CORE_ADDR pc;
-
- if (!skip_subroutines
- && inline_skipped_frames (inferior_ptid))
- {
- ptid_t resume_ptid;
-
- resume_ptid = user_visible_resume_ptid (1);
- set_running (resume_ptid, 1);
- step_into_inline_frame (inferior_ptid);
- if (count > 1)
- step_once (skip_subroutines, single_inst, count - 1, thread);
- else
- {
-
- normal_stop ();
- if (target_can_async_p ())
- inferior_event_handler (INF_EXEC_COMPLETE, NULL);
- }
- return;
- }
- pc = get_frame_pc (frame);
- find_pc_line_pc_range (pc,
- &tp->control.step_range_start,
- &tp->control.step_range_end);
- tp->control.may_range_step = 1;
-
- if (tp->control.step_range_end == 0 && step_stop_if_no_debug)
- {
- tp->control.step_range_start = tp->control.step_range_end = 1;
- tp->control.may_range_step = 0;
- }
- else if (tp->control.step_range_end == 0)
- {
- const char *name;
- if (find_pc_partial_function (pc, &name,
- &tp->control.step_range_start,
- &tp->control.step_range_end) == 0)
- error (_("Cannot find bounds of current function"));
- target_terminal_ours ();
- printf_filtered (_("Single stepping until exit from function %s,"
- "\nwhich has no line number information.\n"),
- name);
- }
- }
- else
- {
-
- tp->control.step_range_start = tp->control.step_range_end = 1;
- if (!skip_subroutines)
-
- tp->control.step_over_calls = STEP_OVER_NONE;
- }
- if (skip_subroutines)
- tp->control.step_over_calls = STEP_OVER_ALL;
- tp->step_multi = (count > 1);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 1);
-
- if (target_can_async_p ())
- {
- struct step_1_continuation_args *args;
- args = xmalloc (sizeof (*args));
- args->skip_subroutines = skip_subroutines;
- args->single_inst = single_inst;
- args->count = count;
- args->thread = thread;
- add_intermediate_continuation (tp, step_1_continuation, args, xfree);
- }
- }
- }
- static void
- jump_command (char *arg, int from_tty)
- {
- struct gdbarch *gdbarch = get_current_arch ();
- CORE_ADDR addr;
- struct symtabs_and_lines sals;
- struct symtab_and_line sal;
- struct symbol *fn;
- struct symbol *sfn;
- int async_exec;
- struct cleanup *args_chain;
- ERROR_NO_INFERIOR;
- ensure_not_tfind_mode ();
- ensure_valid_thread ();
- ensure_not_running ();
-
- arg = strip_bg_char (arg, &async_exec);
- args_chain = make_cleanup (xfree, arg);
- prepare_execution_command (¤t_target, async_exec);
- if (!arg)
- error_no_arg (_("starting address"));
- sals = decode_line_with_last_displayed (arg, DECODE_LINE_FUNFIRSTLINE);
- if (sals.nelts != 1)
- {
- error (_("Unreasonable jump request"));
- }
- sal = sals.sals[0];
- xfree (sals.sals);
-
- do_cleanups (args_chain);
- if (sal.symtab == 0 && sal.pc == 0)
- error (_("No source file has been specified."));
- resolve_sal_pc (&sal);
-
- fn = get_frame_function (get_current_frame ());
- sfn = find_pc_function (sal.pc);
- if (fn != NULL && sfn != fn)
- {
- if (!query (_("Line %d is not in `%s'. Jump anyway? "), sal.line,
- SYMBOL_PRINT_NAME (fn)))
- {
- error (_("Not confirmed."));
-
- }
- }
- if (sfn != NULL)
- {
- struct obj_section *section;
- fixup_symbol_section (sfn, 0);
- section = SYMBOL_OBJ_SECTION (symbol_objfile (sfn), sfn);
- if (section_is_overlay (section)
- && !section_is_mapped (section))
- {
- if (!query (_("WARNING!!! Destination is in "
- "unmapped overlay! Jump anyway? ")))
- {
- error (_("Not confirmed."));
-
- }
- }
- }
- addr = sal.pc;
- if (from_tty)
- {
- printf_filtered (_("Continuing at "));
- fputs_filtered (paddress (gdbarch, addr), gdb_stdout);
- printf_filtered (".\n");
- }
- clear_proceed_status (0);
- proceed (addr, GDB_SIGNAL_0, 0);
- }
- static void
- go_command (char *line_no, int from_tty)
- {
- if (line_no == (char *) NULL || !*line_no)
- printf_filtered (_("Usage: go <location>\n"));
- else
- {
- tbreak_command (line_no, from_tty);
- jump_command (line_no, from_tty);
- }
- }
- static void
- signal_command (char *signum_exp, int from_tty)
- {
- enum gdb_signal oursig;
- int async_exec;
- struct cleanup *args_chain;
- dont_repeat ();
- ERROR_NO_INFERIOR;
- ensure_not_tfind_mode ();
- ensure_valid_thread ();
- ensure_not_running ();
-
- signum_exp = strip_bg_char (signum_exp, &async_exec);
- args_chain = make_cleanup (xfree, signum_exp);
- prepare_execution_command (¤t_target, async_exec);
- if (!signum_exp)
- error_no_arg (_("signal number"));
-
- oursig = gdb_signal_from_name (signum_exp);
- if (oursig == GDB_SIGNAL_UNKNOWN)
- {
-
- int num = parse_and_eval_long (signum_exp);
- if (num == 0)
- oursig = GDB_SIGNAL_0;
- else
- oursig = gdb_signal_from_command (num);
- }
-
- if (!non_stop)
- {
- struct thread_info *tp;
- ptid_t resume_ptid;
- int must_confirm = 0;
-
- resume_ptid = user_visible_resume_ptid (0);
- ALL_NON_EXITED_THREADS (tp)
- {
- if (ptid_equal (tp->ptid, inferior_ptid))
- continue;
- if (!ptid_match (tp->ptid, resume_ptid))
- continue;
- if (tp->suspend.stop_signal != GDB_SIGNAL_0
- && signal_pass_state (tp->suspend.stop_signal))
- {
- if (!must_confirm)
- printf_unfiltered (_("Note:\n"));
- printf_unfiltered (_(" Thread %d previously stopped with signal %s, %s.\n"),
- tp->num,
- gdb_signal_to_name (tp->suspend.stop_signal),
- gdb_signal_to_string (tp->suspend.stop_signal));
- must_confirm = 1;
- }
- }
- if (must_confirm
- && !query (_("Continuing thread %d (the current thread) with specified signal will\n"
- "still deliver the signals noted above to their respective threads.\n"
- "Continue anyway? "),
- inferior_thread ()->num))
- error (_("Not confirmed."));
- }
- if (from_tty)
- {
- if (oursig == GDB_SIGNAL_0)
- printf_filtered (_("Continuing with no signal.\n"));
- else
- printf_filtered (_("Continuing with signal %s.\n"),
- gdb_signal_to_name (oursig));
- }
- clear_proceed_status (0);
- proceed ((CORE_ADDR) -1, oursig, 0);
- }
- static void
- queue_signal_command (char *signum_exp, int from_tty)
- {
- enum gdb_signal oursig;
- struct thread_info *tp;
- ERROR_NO_INFERIOR;
- ensure_not_tfind_mode ();
- ensure_valid_thread ();
- ensure_not_running ();
- if (signum_exp == NULL)
- error_no_arg (_("signal number"));
-
- oursig = gdb_signal_from_name (signum_exp);
- if (oursig == GDB_SIGNAL_UNKNOWN)
- {
-
- int num = parse_and_eval_long (signum_exp);
- if (num == 0)
- oursig = GDB_SIGNAL_0;
- else
- oursig = gdb_signal_from_command (num);
- }
- if (oursig != GDB_SIGNAL_0
- && !signal_pass_state (oursig))
- error (_("Signal handling set to not pass this signal to the program."));
- tp = inferior_thread ();
- tp->suspend.stop_signal = oursig;
- }
- struct until_next_continuation_args
- {
-
- int thread;
- };
- static void
- until_next_continuation (void *arg, int err)
- {
- struct until_next_continuation_args *a = arg;
- delete_longjmp_breakpoint (a->thread);
- }
- static void
- until_next_command (int from_tty)
- {
- struct frame_info *frame;
- CORE_ADDR pc;
- struct symbol *func;
- struct symtab_and_line sal;
- struct thread_info *tp = inferior_thread ();
- int thread = tp->num;
- struct cleanup *old_chain;
- clear_proceed_status (0);
- set_step_frame ();
- frame = get_current_frame ();
-
- pc = get_frame_pc (frame);
- func = find_pc_function (pc);
- if (!func)
- {
- struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc);
- if (msymbol.minsym == NULL)
- error (_("Execution is not within a known function."));
- tp->control.step_range_start = BMSYMBOL_VALUE_ADDRESS (msymbol);
-
- tp->control.step_range_end = pc + 1;
- }
- else
- {
- sal = find_pc_line (pc, 0);
- tp->control.step_range_start = BLOCK_START (SYMBOL_BLOCK_VALUE (func));
- tp->control.step_range_end = sal.end;
- }
- tp->control.may_range_step = 1;
- tp->control.step_over_calls = STEP_OVER_ALL;
- tp->step_multi = 0;
- set_longjmp_breakpoint (tp, get_frame_id (frame));
- old_chain = make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 1);
- if (target_can_async_p () && is_running (inferior_ptid))
- {
- struct until_next_continuation_args *cont_args;
- discard_cleanups (old_chain);
- cont_args = XNEW (struct until_next_continuation_args);
- cont_args->thread = inferior_thread ()->num;
- add_continuation (tp, until_next_continuation, cont_args, xfree);
- }
- else
- do_cleanups (old_chain);
- }
- static void
- until_command (char *arg, int from_tty)
- {
- int async_exec;
- struct cleanup *args_chain;
- ERROR_NO_INFERIOR;
- ensure_not_tfind_mode ();
- ensure_valid_thread ();
- ensure_not_running ();
-
- arg = strip_bg_char (arg, &async_exec);
- args_chain = make_cleanup (xfree, arg);
- prepare_execution_command (¤t_target, async_exec);
- if (arg)
- until_break_command (arg, from_tty, 0);
- else
- until_next_command (from_tty);
-
- do_cleanups (args_chain);
- }
- static void
- advance_command (char *arg, int from_tty)
- {
- int async_exec;
- struct cleanup *args_chain;
- ERROR_NO_INFERIOR;
- ensure_not_tfind_mode ();
- ensure_valid_thread ();
- ensure_not_running ();
- if (arg == NULL)
- error_no_arg (_("a location"));
-
- arg = strip_bg_char (arg, &async_exec);
- args_chain = make_cleanup (xfree, arg);
- prepare_execution_command (¤t_target, async_exec);
- until_break_command (arg, from_tty, 1);
-
- do_cleanups (args_chain);
- }
- struct value *
- get_return_value (struct value *function, struct type *value_type)
- {
- struct regcache *stop_regs = stop_registers;
- struct gdbarch *gdbarch;
- struct value *value;
- struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
-
- if (!stop_regs)
- {
- stop_regs = regcache_dup (get_current_regcache ());
- make_cleanup_regcache_xfree (stop_regs);
- }
- gdbarch = get_regcache_arch (stop_regs);
- CHECK_TYPEDEF (value_type);
- gdb_assert (TYPE_CODE (value_type) != TYPE_CODE_VOID);
- FIXME
- switch (gdbarch_return_value (gdbarch, function, value_type,
- NULL, NULL, NULL))
- {
- case RETURN_VALUE_REGISTER_CONVENTION:
- case RETURN_VALUE_ABI_RETURNS_ADDRESS:
- case RETURN_VALUE_ABI_PRESERVES_ADDRESS:
- value = allocate_value (value_type);
- gdbarch_return_value (gdbarch, function, value_type, stop_regs,
- value_contents_raw (value), NULL);
- break;
- case RETURN_VALUE_STRUCT_CONVENTION:
- value = NULL;
- break;
- default:
- internal_error (__FILE__, __LINE__, _("bad switch"));
- }
- do_cleanups (cleanup);
- return value;
- }
- static void
- print_return_value (struct value *function, struct type *value_type)
- {
- struct value *value = get_return_value (function, value_type);
- struct ui_out *uiout = current_uiout;
- if (value)
- {
- struct value_print_options opts;
- struct ui_file *stb;
- struct cleanup *old_chain;
-
- stb = mem_fileopen ();
- old_chain = make_cleanup_ui_file_delete (stb);
- ui_out_text (uiout, "Value returned is ");
- ui_out_field_fmt (uiout, "gdb-result-var", "$%d",
- record_latest_value (value));
- ui_out_text (uiout, " = ");
- get_no_prettyformat_print_options (&opts);
- value_print (value, stb, &opts);
- ui_out_field_stream (uiout, "return-value", stb);
- ui_out_text (uiout, "\n");
- do_cleanups (old_chain);
- }
- else
- {
- ui_out_text (uiout, "Value returned has type: ");
- ui_out_field_string (uiout, "return-type", TYPE_NAME (value_type));
- ui_out_text (uiout, ".");
- ui_out_text (uiout, " Cannot determine contents\n");
- }
- }
- struct finish_command_continuation_args
- {
-
- int thread;
- struct breakpoint *breakpoint;
- struct symbol *function;
- };
- static void
- finish_command_continuation (void *arg, int err)
- {
- struct finish_command_continuation_args *a = arg;
- if (!err)
- {
- struct thread_info *tp = NULL;
- bpstat bs = NULL;
- if (!ptid_equal (inferior_ptid, null_ptid)
- && target_has_execution
- && is_stopped (inferior_ptid))
- {
- tp = inferior_thread ();
- bs = tp->control.stop_bpstat;
- }
- if (bpstat_find_breakpoint (bs, a->breakpoint) != NULL
- && a->function != NULL)
- {
- struct type *value_type;
- value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (a->function));
- if (!value_type)
- internal_error (__FILE__, __LINE__,
- _("finish_command: function has no target type"));
- if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
- {
- volatile struct gdb_exception ex;
- struct value *func;
- func = read_var_value (a->function, get_current_frame ());
- TRY_CATCH (ex, RETURN_MASK_ALL)
- {
-
- print_return_value (func, value_type);
- }
- if (ex.reason < 0)
- exception_print (gdb_stdout, ex);
- }
- }
-
- if (bs != NULL && tp->control.proceed_to_finish)
- observer_notify_normal_stop (bs, 1 );
- }
- delete_breakpoint (a->breakpoint);
- delete_longjmp_breakpoint (a->thread);
- }
- static void
- finish_command_continuation_free_arg (void *arg)
- {
- xfree (arg);
- }
- static void
- finish_backward (struct symbol *function)
- {
- struct symtab_and_line sal;
- struct thread_info *tp = inferior_thread ();
- CORE_ADDR pc;
- CORE_ADDR func_addr;
- pc = get_frame_pc (get_current_frame ());
- if (find_pc_partial_function (pc, NULL, &func_addr, NULL) == 0)
- error (_("Cannot find bounds of current function"));
- sal = find_pc_line (func_addr, 0);
- tp->control.proceed_to_finish = 1;
-
- if (sal.pc != pc)
- {
- struct frame_info *frame = get_selected_frame (NULL);
- struct gdbarch *gdbarch = get_frame_arch (frame);
- struct symtab_and_line sr_sal;
-
- init_sal (&sr_sal);
- sr_sal.pc = sal.pc;
- sr_sal.pspace = get_frame_program_space (frame);
- insert_step_resume_breakpoint_at_sal (gdbarch,
- sr_sal, null_frame_id);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
- }
- else
- {
-
- tp->control.step_range_start = tp->control.step_range_end = 1;
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 1);
- }
- }
- static void
- finish_forward (struct symbol *function, struct frame_info *frame)
- {
- struct frame_id frame_id = get_frame_id (frame);
- struct gdbarch *gdbarch = get_frame_arch (frame);
- struct symtab_and_line sal;
- struct thread_info *tp = inferior_thread ();
- struct breakpoint *breakpoint;
- struct cleanup *old_chain;
- struct finish_command_continuation_args *cargs;
- int thread = tp->num;
- sal = find_pc_line (get_frame_pc (frame), 0);
- sal.pc = get_frame_pc (frame);
- breakpoint = set_momentary_breakpoint (gdbarch, sal,
- get_stack_frame_id (frame),
- bp_finish);
-
- frame = NULL;
- old_chain = make_cleanup_delete_breakpoint (breakpoint);
- set_longjmp_breakpoint (tp, frame_id);
- make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
-
- tp->control.proceed_to_finish = 1;
- cargs = xmalloc (sizeof (*cargs));
- cargs->thread = thread;
- cargs->breakpoint = breakpoint;
- cargs->function = function;
- add_continuation (tp, finish_command_continuation, cargs,
- finish_command_continuation_free_arg);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
- discard_cleanups (old_chain);
- if (!target_can_async_p ())
- do_all_continuations (0);
- }
- static void
- finish_command (char *arg, int from_tty)
- {
- struct frame_info *frame;
- struct symbol *function;
- int async_exec;
- struct cleanup *args_chain;
- ERROR_NO_INFERIOR;
- ensure_not_tfind_mode ();
- ensure_valid_thread ();
- ensure_not_running ();
-
- arg = strip_bg_char (arg, &async_exec);
- args_chain = make_cleanup (xfree, arg);
- prepare_execution_command (¤t_target, async_exec);
- if (arg)
- error (_("The \"finish\" command does not take any arguments."));
-
- do_cleanups (args_chain);
- frame = get_prev_frame (get_selected_frame (_("No selected frame.")));
- if (frame == 0)
- error (_("\"finish\" not meaningful in the outermost frame."));
- clear_proceed_status (0);
-
- if (get_frame_type (get_selected_frame (_("No selected frame.")))
- == INLINE_FRAME)
- {
-
- struct thread_info *tp = inferior_thread ();
- struct symtab_and_line empty_sal;
- init_sal (&empty_sal);
- set_step_info (frame, empty_sal);
- tp->control.step_range_start = get_frame_pc (frame);
- tp->control.step_range_end = tp->control.step_range_start;
- tp->control.step_over_calls = STEP_OVER_ALL;
-
- if (from_tty)
- {
- printf_filtered (_("Run till exit from "));
- print_stack_frame (get_selected_frame (NULL), 1, LOCATION, 0);
- }
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 1);
- return;
- }
-
- while (get_frame_type (frame) == TAILCALL_FRAME)
- frame = get_prev_frame (frame);
-
- function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
-
- if (from_tty)
- {
- if (execution_direction == EXEC_REVERSE)
- printf_filtered (_("Run back to call of "));
- else
- printf_filtered (_("Run till exit from "));
- print_stack_frame (get_selected_frame (NULL), 1, LOCATION, 0);
- }
- if (execution_direction == EXEC_REVERSE)
- finish_backward (function);
- else
- finish_forward (function, frame);
- }
- static void
- program_info (char *args, int from_tty)
- {
- bpstat bs;
- int num, stat;
- struct thread_info *tp;
- ptid_t ptid;
- if (!target_has_execution)
- {
- printf_filtered (_("The program being debugged is not being run.\n"));
- return;
- }
- if (non_stop)
- ptid = inferior_ptid;
- else
- {
- struct target_waitstatus ws;
- get_last_target_status (&ptid, &ws);
- }
- if (ptid_equal (ptid, null_ptid) || is_exited (ptid))
- error (_("Invalid selected thread."));
- else if (is_running (ptid))
- error (_("Selected thread is running."));
- tp = find_thread_ptid (ptid);
- bs = tp->control.stop_bpstat;
- stat = bpstat_num (&bs, &num);
- target_files_info ();
- printf_filtered (_("Program stopped at %s.\n"),
- paddress (target_gdbarch (), stop_pc));
- if (tp->control.stop_step)
- printf_filtered (_("It stopped after being stepped.\n"));
- else if (stat != 0)
- {
-
- while (stat != 0)
- {
- if (stat < 0)
- {
- printf_filtered (_("It stopped at a breakpoint "
- "that has since been deleted.\n"));
- }
- else
- printf_filtered (_("It stopped at breakpoint %d.\n"), num);
- stat = bpstat_num (&bs, &num);
- }
- }
- else if (tp->suspend.stop_signal != GDB_SIGNAL_0)
- {
- printf_filtered (_("It stopped with signal %s, %s.\n"),
- gdb_signal_to_name (tp->suspend.stop_signal),
- gdb_signal_to_string (tp->suspend.stop_signal));
- }
- if (from_tty)
- {
- printf_filtered (_("Type \"info stack\" or \"info "
- "registers\" for more information.\n"));
- }
- }
- static void
- environment_info (char *var, int from_tty)
- {
- if (var)
- {
- char *val = get_in_environ (current_inferior ()->environment, var);
- if (val)
- {
- puts_filtered (var);
- puts_filtered (" = ");
- puts_filtered (val);
- puts_filtered ("\n");
- }
- else
- {
- puts_filtered ("Environment variable \"");
- puts_filtered (var);
- puts_filtered ("\" not defined.\n");
- }
- }
- else
- {
- char **vector = environ_vector (current_inferior ()->environment);
- while (*vector)
- {
- puts_filtered (*vector++);
- puts_filtered ("\n");
- }
- }
- }
- static void
- set_environment_command (char *arg, int from_tty)
- {
- char *p, *val, *var;
- int nullset = 0;
- if (arg == 0)
- error_no_arg (_("environment variable and value"));
-
- p = (char *) strchr (arg, '=');
- val = (char *) strchr (arg, ' ');
- if (p != 0 && val != 0)
- {
-
- if (p > val)
- while (*val == ' ')
- val++;
-
- if (p > val)
- p = val - 1;
- }
- else if (val != 0 && p == 0)
- p = val;
- if (p == arg)
- error_no_arg (_("environment variable to set"));
- if (p == 0 || p[1] == 0)
- {
- nullset = 1;
- if (p == 0)
- p = arg + strlen (arg);
- }
- else
- {
-
- val = p + 1;
- while (*val == ' ' || *val == '\t')
- val++;
- }
- while (p != arg && (p[-1] == ' ' || p[-1] == '\t'))
- p--;
- var = savestring (arg, p - arg);
- if (nullset)
- {
- printf_filtered (_("Setting environment variable "
- "\"%s\" to null value.\n"),
- var);
- set_in_environ (current_inferior ()->environment, var, "");
- }
- else
- set_in_environ (current_inferior ()->environment, var, val);
- xfree (var);
- }
- static void
- unset_environment_command (char *var, int from_tty)
- {
- if (var == 0)
- {
-
- if (!from_tty || query (_("Delete all environment variables? ")))
- {
- free_environ (current_inferior ()->environment);
- current_inferior ()->environment = make_environ ();
- }
- }
- else
- unset_in_environ (current_inferior ()->environment, var);
- }
- static const char path_var_name[] = "PATH";
- static void
- path_info (char *args, int from_tty)
- {
- puts_filtered ("Executable and object file path: ");
- puts_filtered (get_in_environ (current_inferior ()->environment,
- path_var_name));
- puts_filtered ("\n");
- }
- static void
- path_command (char *dirname, int from_tty)
- {
- char *exec_path;
- char *env;
- dont_repeat ();
- env = get_in_environ (current_inferior ()->environment, path_var_name);
-
- if (!env)
- env = "";
- exec_path = xstrdup (env);
- mod_path (dirname, &exec_path);
- set_in_environ (current_inferior ()->environment, path_var_name, exec_path);
- xfree (exec_path);
- if (from_tty)
- path_info ((char *) NULL, from_tty);
- }
- static void
- default_print_one_register_info (struct ui_file *file,
- const char *name,
- struct value *val)
- {
- struct type *regtype = value_type (val);
- int print_raw_format;
- fputs_filtered (name, file);
- print_spaces_filtered (15 - strlen (name), file);
- print_raw_format = (value_entirely_available (val)
- && !value_optimized_out (val));
-
- if (TYPE_CODE (regtype) == TYPE_CODE_FLT
- || TYPE_CODE (regtype) == TYPE_CODE_DECFLOAT)
- {
- int j;
- struct value_print_options opts;
- const gdb_byte *valaddr = value_contents_for_printing (val);
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (regtype));
- get_user_print_options (&opts);
- opts.deref_ref = 1;
- val_print (regtype,
- value_contents_for_printing (val),
- value_embedded_offset (val), 0,
- file, 0, val, &opts, current_language);
- if (print_raw_format)
- {
- fprintf_filtered (file, "\t(raw ");
- print_hex_chars (file, valaddr, TYPE_LENGTH (regtype), byte_order);
- fprintf_filtered (file, ")");
- }
- }
- else
- {
- struct value_print_options opts;
-
- get_formatted_print_options (&opts, 'x');
- opts.deref_ref = 1;
- val_print (regtype,
- value_contents_for_printing (val),
- value_embedded_offset (val), 0,
- file, 0, val, &opts, current_language);
-
- if (print_raw_format && TYPE_VECTOR (regtype) == 0)
- {
- get_user_print_options (&opts);
- opts.deref_ref = 1;
- fprintf_filtered (file, "\t");
- val_print (regtype,
- value_contents_for_printing (val),
- value_embedded_offset (val), 0,
- file, 0, val, &opts, current_language);
- }
- }
- fprintf_filtered (file, "\n");
- }
- void
- default_print_registers_info (struct gdbarch *gdbarch,
- struct ui_file *file,
- struct frame_info *frame,
- int regnum, int print_all)
- {
- int i;
- const int numregs = gdbarch_num_regs (gdbarch)
- + gdbarch_num_pseudo_regs (gdbarch);
- for (i = 0; i < numregs; i++)
- {
-
- if (regnum == -1)
- {
- if (print_all)
- {
- if (!gdbarch_register_reggroup_p (gdbarch, i, all_reggroup))
- continue;
- }
- else
- {
- if (!gdbarch_register_reggroup_p (gdbarch, i, general_reggroup))
- continue;
- }
- }
- else
- {
- if (i != regnum)
- continue;
- }
-
- if (gdbarch_register_name (gdbarch, i) == NULL
- || *(gdbarch_register_name (gdbarch, i)) == '\0')
- continue;
- default_print_one_register_info (file,
- gdbarch_register_name (gdbarch, i),
- value_of_register (i, frame));
- }
- }
- void
- registers_info (char *addr_exp, int fpregs)
- {
- struct frame_info *frame;
- struct gdbarch *gdbarch;
- if (!target_has_registers)
- error (_("The program has no registers now."));
- frame = get_selected_frame (NULL);
- gdbarch = get_frame_arch (frame);
- if (!addr_exp)
- {
- gdbarch_print_registers_info (gdbarch, gdb_stdout,
- frame, -1, fpregs);
- return;
- }
- while (*addr_exp != '\0')
- {
- char *start;
- const char *end;
-
- addr_exp = skip_spaces (addr_exp);
-
- if (addr_exp[0] == '$')
- addr_exp++;
- if (isspace ((*addr_exp)) || (*addr_exp) == '\0')
- error (_("Missing register name"));
-
- start = addr_exp;
- while ((*addr_exp) != '\0' && !isspace ((*addr_exp)))
- addr_exp++;
- end = addr_exp;
-
-
- {
- int regnum = user_reg_map_name_to_regnum (gdbarch, start, end - start);
- if (regnum >= 0)
- {
-
- if (regnum >= gdbarch_num_regs (gdbarch)
- + gdbarch_num_pseudo_regs (gdbarch))
- {
- struct value *regval = value_of_user_reg (regnum, frame);
- const char *regname = user_reg_map_regnum_to_name (gdbarch,
- regnum);
-
- default_print_one_register_info (gdb_stdout,
- regname,
- regval);
- }
- else
- gdbarch_print_registers_info (gdbarch, gdb_stdout,
- frame, regnum, fpregs);
- continue;
- }
- }
-
- {
- struct reggroup *group;
- for (group = reggroup_next (gdbarch, NULL);
- group != NULL;
- group = reggroup_next (gdbarch, group))
- {
-
- if (strncmp (start, reggroup_name (group), end - start) == 0)
- break;
- }
- if (group != NULL)
- {
- int regnum;
- for (regnum = 0;
- regnum < gdbarch_num_regs (gdbarch)
- + gdbarch_num_pseudo_regs (gdbarch);
- regnum++)
- {
- if (gdbarch_register_reggroup_p (gdbarch, regnum, group))
- gdbarch_print_registers_info (gdbarch,
- gdb_stdout, frame,
- regnum, fpregs);
- }
- continue;
- }
- }
-
- error (_("Invalid register `%.*s'"), (int) (end - start), start);
- }
- }
- static void
- all_registers_info (char *addr_exp, int from_tty)
- {
- registers_info (addr_exp, 1);
- }
- static void
- nofp_registers_info (char *addr_exp, int from_tty)
- {
- registers_info (addr_exp, 0);
- }
- static void
- print_vector_info (struct ui_file *file,
- struct frame_info *frame, const char *args)
- {
- struct gdbarch *gdbarch = get_frame_arch (frame);
- if (gdbarch_print_vector_info_p (gdbarch))
- gdbarch_print_vector_info (gdbarch, file, frame, args);
- else
- {
- int regnum;
- int printed_something = 0;
- for (regnum = 0;
- regnum < gdbarch_num_regs (gdbarch)
- + gdbarch_num_pseudo_regs (gdbarch);
- regnum++)
- {
- if (gdbarch_register_reggroup_p (gdbarch, regnum, vector_reggroup))
- {
- printed_something = 1;
- gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1);
- }
- }
- if (!printed_something)
- fprintf_filtered (file, "No vector information\n");
- }
- }
- static void
- vector_info (char *args, int from_tty)
- {
- if (!target_has_registers)
- error (_("The program has no registers now."));
- print_vector_info (gdb_stdout, get_selected_frame (NULL), args);
- }
- static void
- kill_command (char *arg, int from_tty)
- {
- FIXME
- if (ptid_equal (inferior_ptid, null_ptid))
- error (_("The program is not being run."));
- if (!query (_("Kill the program being debugged? ")))
- error (_("Not confirmed."));
- target_kill ();
-
- if (!have_inferiors ())
- {
- init_thread_list ();
-
- if (target_has_stack)
- {
- printf_filtered (_("In %s,\n"), target_longname);
- print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
- }
- }
- bfd_cache_close_all ();
- }
- static int
- proceed_after_attach_callback (struct thread_info *thread,
- void *arg)
- {
- int pid = * (int *) arg;
- if (ptid_get_pid (thread->ptid) == pid
- && !is_exited (thread->ptid)
- && !is_executing (thread->ptid)
- && !thread->stop_requested
- && thread->suspend.stop_signal == GDB_SIGNAL_0)
- {
- switch_to_thread (thread->ptid);
- clear_proceed_status (0);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
- }
- return 0;
- }
- static void
- proceed_after_attach (int pid)
- {
-
- struct cleanup *old_chain;
-
- old_chain = make_cleanup_restore_current_thread ();
- iterate_over_threads (proceed_after_attach_callback, &pid);
-
- do_cleanups (old_chain);
- }
- static void
- attach_command_post_wait (char *args, int from_tty, int async_exec)
- {
- char *exec_file;
- char *full_exec_path = NULL;
- struct inferior *inferior;
- inferior = current_inferior ();
- inferior->control.stop_soon = NO_STOP_QUIETLY;
-
- exec_file = (char *) get_exec_file (0);
- if (!exec_file)
- {
- exec_file = target_pid_to_exec_file (ptid_get_pid (inferior_ptid));
- if (exec_file)
- {
-
- if (!source_full_path_of (exec_file, &full_exec_path))
- full_exec_path = xstrdup (exec_file);
- exec_file_attach (full_exec_path, from_tty);
- symbol_file_add_main (full_exec_path, from_tty);
- }
- }
- else
- {
- reopen_exec_file ();
- reread_symbols ();
- }
-
- target_post_attach (ptid_get_pid (inferior_ptid));
- post_create_inferior (¤t_target, from_tty);
- if (async_exec)
- {
-
-
- if (non_stop)
- proceed_after_attach (inferior->pid);
- else
- {
- if (inferior_thread ()->suspend.stop_signal == GDB_SIGNAL_0)
- {
- clear_proceed_status (0);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
- }
- }
- }
- else
- {
-
- if (target_can_async_p ())
- async_enable_stdin ();
-
-
- if (non_stop)
- target_stop (pid_to_ptid (inferior->pid));
-
- normal_stop ();
- if (deprecated_attach_hook)
- deprecated_attach_hook ();
- }
- }
- struct attach_command_continuation_args
- {
- char *args;
- int from_tty;
- int async_exec;
- };
- static void
- attach_command_continuation (void *args, int err)
- {
- struct attach_command_continuation_args *a = args;
- if (err)
- return;
- attach_command_post_wait (a->args, a->from_tty, a->async_exec);
- }
- static void
- attach_command_continuation_free_args (void *args)
- {
- struct attach_command_continuation_args *a = args;
- xfree (a->args);
- xfree (a);
- }
- void
- attach_command (char *args, int from_tty)
- {
- int async_exec;
- struct cleanup *args_chain;
- struct target_ops *attach_target;
- dont_repeat ();
- if (gdbarch_has_global_solist (target_gdbarch ()))
-
- ;
- else if (target_has_execution)
- {
- if (query (_("A program is being debugged already. Kill it? ")))
- target_kill ();
- else
- error (_("Not killed."));
- }
-
- target_pre_inferior (from_tty);
- args = strip_bg_char (args, &async_exec);
- args_chain = make_cleanup (xfree, args);
- attach_target = find_attach_target ();
- prepare_execution_command (attach_target, async_exec);
- if (non_stop && !attach_target->to_supports_non_stop (attach_target))
- error (_("Cannot attach to this target in non-stop mode"));
- attach_target->to_attach (attach_target, args, from_tty);
-
- attach_target = NULL;
-
- do_cleanups (args_chain);
-
- target_terminal_init ();
-
- target_terminal_inferior ();
-
- init_wait_for_inferior ();
- clear_proceed_status (0);
- if (non_stop)
- {
-
- if (async_exec)
-
- target_stop (inferior_ptid);
- else
-
- target_stop (pid_to_ptid (ptid_get_pid (inferior_ptid)));
- }
-
- if (!target_attach_no_wait)
- {
- struct inferior *inferior = current_inferior ();
-
- inferior->control.stop_soon = STOP_QUIETLY_NO_SIGSTOP;
- if (target_can_async_p ())
- {
-
- struct attach_command_continuation_args *a;
- a = xmalloc (sizeof (*a));
- a->args = xstrdup (args);
- a->from_tty = from_tty;
- a->async_exec = async_exec;
- add_inferior_continuation (attach_command_continuation, a,
- attach_command_continuation_free_args);
- return;
- }
- wait_for_inferior ();
- }
- attach_command_post_wait (args, from_tty, async_exec);
- }
- void
- notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
- {
- struct cleanup* old_chain;
- int async_exec;
- old_chain = make_cleanup (null_cleanup, NULL);
-
- async_exec = non_stop;
- if (!ptid_equal (inferior_ptid, null_ptid))
- make_cleanup_restore_current_thread ();
- switch_to_thread (ptid);
-
- if (is_executing (inferior_ptid))
- {
- struct inferior *inferior = current_inferior ();
-
- target_stop (inferior_ptid);
- inferior->control.stop_soon = STOP_QUIETLY_REMOTE;
-
- if (target_can_async_p ())
- {
- struct attach_command_continuation_args *a;
- a = xmalloc (sizeof (*a));
- a->args = xstrdup ("");
- a->from_tty = from_tty;
- a->async_exec = async_exec;
- add_inferior_continuation (attach_command_continuation, a,
- attach_command_continuation_free_args);
- do_cleanups (old_chain);
- return;
- }
- else
- wait_for_inferior ();
- }
- async_exec = leave_running;
- attach_command_post_wait ("" , from_tty, async_exec);
- do_cleanups (old_chain);
- }
- void
- detach_command (char *args, int from_tty)
- {
- dont_repeat ();
- if (ptid_equal (inferior_ptid, null_ptid))
- error (_("The program is not being run."));
- query_if_trace_running (from_tty);
- disconnect_tracing ();
- target_detach (args, from_tty);
-
- if (!gdbarch_has_global_solist (target_gdbarch ()))
- no_shared_libraries (NULL, from_tty);
-
- if (!have_inferiors ())
- init_thread_list ();
- if (deprecated_detach_hook)
- deprecated_detach_hook ();
- }
- static void
- disconnect_command (char *args, int from_tty)
- {
- dont_repeat ();
- query_if_trace_running (from_tty);
- disconnect_tracing ();
- target_disconnect (args, from_tty);
- no_shared_libraries (NULL, from_tty);
- init_thread_list ();
- if (deprecated_detach_hook)
- deprecated_detach_hook ();
- }
- void
- interrupt_target_1 (int all_threads)
- {
- ptid_t ptid;
- if (all_threads)
- ptid = minus_one_ptid;
- else
- ptid = inferior_ptid;
- target_stop (ptid);
-
- if (non_stop)
- set_stop_requested (ptid, 1);
- }
- static void
- interrupt_command (char *args, int from_tty)
- {
- if (target_can_async_p ())
- {
- int all_threads = 0;
- dont_repeat ();
- if (args != NULL
- && strncmp (args, "-a", sizeof ("-a") - 1) == 0)
- all_threads = 1;
- if (!non_stop && all_threads)
- error (_("-a is meaningless in all-stop mode."));
- interrupt_target_1 (all_threads);
- }
- }
- void
- default_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
- struct frame_info *frame, const char *args)
- {
- int regnum;
- int printed_something = 0;
- for (regnum = 0;
- regnum < gdbarch_num_regs (gdbarch)
- + gdbarch_num_pseudo_regs (gdbarch);
- regnum++)
- {
- if (gdbarch_register_reggroup_p (gdbarch, regnum, float_reggroup))
- {
- printed_something = 1;
- gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1);
- }
- }
- if (!printed_something)
- fprintf_filtered (file, "No floating-point info "
- "available for this processor.\n");
- }
- static void
- float_info (char *args, int from_tty)
- {
- struct frame_info *frame;
- if (!target_has_registers)
- error (_("The program has no registers now."));
- frame = get_selected_frame (NULL);
- gdbarch_print_float_info (get_frame_arch (frame), gdb_stdout, frame, args);
- }
- static void
- unset_command (char *args, int from_tty)
- {
- printf_filtered (_("\"unset\" must be followed by the "
- "name of an unset subcommand.\n"));
- help_list (unsetlist, "unset ", all_commands, gdb_stdout);
- }
- static void
- info_proc_cmd_1 (char *args, enum info_proc_what what, int from_tty)
- {
- struct gdbarch *gdbarch = get_current_arch ();
- if (!target_info_proc (args, what))
- {
- if (gdbarch_info_proc_p (gdbarch))
- gdbarch_info_proc (gdbarch, args, what);
- else
- error (_("Not supported on this target."));
- }
- }
- static void
- info_proc_cmd (char *args, int from_tty)
- {
- info_proc_cmd_1 (args, IP_MINIMAL, from_tty);
- }
- static void
- info_proc_cmd_mappings (char *args, int from_tty)
- {
- info_proc_cmd_1 (args, IP_MAPPINGS, from_tty);
- }
- static void
- info_proc_cmd_stat (char *args, int from_tty)
- {
- info_proc_cmd_1 (args, IP_STAT, from_tty);
- }
- static void
- info_proc_cmd_status (char *args, int from_tty)
- {
- info_proc_cmd_1 (args, IP_STATUS, from_tty);
- }
- static void
- info_proc_cmd_cwd (char *args, int from_tty)
- {
- info_proc_cmd_1 (args, IP_CWD, from_tty);
- }
- static void
- info_proc_cmd_cmdline (char *args, int from_tty)
- {
- info_proc_cmd_1 (args, IP_CMDLINE, from_tty);
- }
- static void
- info_proc_cmd_exe (char *args, int from_tty)
- {
- info_proc_cmd_1 (args, IP_EXE, from_tty);
- }
- static void
- info_proc_cmd_all (char *args, int from_tty)
- {
- info_proc_cmd_1 (args, IP_ALL, from_tty);
- }
- void
- _initialize_infcmd (void)
- {
- static struct cmd_list_element *info_proc_cmdlist;
- struct cmd_list_element *c = NULL;
- const char *cmd_name;
-
- add_setshow_filename_cmd ("inferior-tty", class_run,
- &inferior_io_terminal_scratch, _("\
- Set terminal for future runs of program being debugged."), _("\
- Show terminal for future runs of program being debugged."), _("\
- Usage: set inferior-tty /dev/pts/1"),
- set_inferior_tty_command,
- show_inferior_tty_command,
- &setlist, &showlist);
- add_com_alias ("tty", "set inferior-tty", class_alias, 0);
- cmd_name = "args";
- add_setshow_string_noescape_cmd (cmd_name, class_run,
- &inferior_args_scratch, _("\
- Set argument list to give program being debugged when it is started."), _("\
- Show argument list to give program being debugged when it is started."), _("\
- Follow this command with any number of args, to be passed to the program."),
- set_args_command,
- show_args_command,
- &setlist, &showlist);
- c = lookup_cmd (&cmd_name, setlist, "", -1, 1);
- gdb_assert (c != NULL);
- set_cmd_completer (c, filename_completer);
- c = add_cmd ("environment", no_class, environment_info, _("\
- The environment to give the program, or one variable's value.\n\
- 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."), &showlist);
- set_cmd_completer (c, noop_completer);
- add_prefix_cmd ("unset", no_class, unset_command,
- _("Complement to certain \"set\" commands."),
- &unsetlist, "unset ", 0, &cmdlist);
- c = 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."),
- &unsetlist);
- set_cmd_completer (c, noop_completer);
- c = 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."),
- &setlist);
- set_cmd_completer (c, noop_completer);
- c = add_com ("path", class_files, path_command, _("\
- Add directory DIR(s) to beginning of search path for object files.\n\
- $cwd in the path means the current working directory.\n\
- This path is equivalent to the $PATH shell variable. It is a list of\n\
- directories, separated by colons. These directories are searched to find\n\
- fully linked executable files and separately compiled object files as \
- needed."));
- set_cmd_completer (c, filename_completer);
- c = add_cmd ("paths", no_class, path_info, _("\
- Current search path for finding object files.\n\
- $cwd in the path means the current working directory.\n\
- This path is equivalent to the $PATH shell variable. It is a list of\n\
- directories, separated by colons. These directories are searched to find\n\
- fully linked executable files and separately compiled object files as \
- needed."),
- &showlist);
- set_cmd_completer (c, noop_completer);
- add_prefix_cmd ("kill", class_run, kill_command,
- _("Kill execution of program being debugged."),
- &killlist, "kill ", 0, &cmdlist);
- add_com ("attach", class_run, attach_command, _("\
- Attach to a process or file outside of GDB.\n\
- This command attaches to another target, of the same type as your last\n\
- \"target\" command (\"info files\" will show your target stack).\n\
- The command may take as argument a process id or a device file.\n\
- For a process id, you must have permission to send the process a signal,\n\
- and it must have the same effective uid as the debugger.\n\
- When using \"attach\" with a process id, the debugger finds the\n\
- program running in the process, looking first in the current working\n\
- directory, or (if not found there) using the source file search path\n\
- (see the \"directory\" command). You can also use the \"file\" command\n\
- to specify the program, and to load its symbol table."));
- add_prefix_cmd ("detach", class_run, detach_command, _("\
- Detach a process or file previously attached.\n\
- If a process, it is no longer traced, and it continues its execution. If\n\
- you were debugging a file, the file is closed and gdb no longer accesses it."),
- &detachlist, "detach ", 0, &cmdlist);
- add_com ("disconnect", class_run, disconnect_command, _("\
- Disconnect from a target.\n\
- The target will wait for another debugger to connect. Not available for\n\
- all targets."));
- c = add_com ("signal", class_run, signal_command, _("\
- Continue program with the specified signal.\n\
- Usage: signal SIGNAL\n\
- The SIGNAL argument is processed the same as the handle command.\n\
- \n\
- An argument of \"0\" means continue the program without sending it a signal.\n\
- This is useful in cases where the program stopped because of a signal,\n\
- and you want to resume the program while discarding the signal.\n\
- \n\
- In a multi-threaded program the signal is delivered to, or discarded from,\n\
- the current thread only."));
- set_cmd_completer (c, signal_completer);
- c = add_com ("queue-signal", class_run, queue_signal_command, _("\
- Queue a signal to be delivered to the current thread when it is resumed.\n\
- Usage: queue-signal SIGNAL\n\
- The SIGNAL argument is processed the same as the handle command.\n\
- It is an error if the handling state of SIGNAL is \"nopass\".\n\
- \n\
- An argument of \"0\" means remove any currently queued signal from\n\
- the current thread. This is useful in cases where the program stopped\n\
- because of a signal, and you want to resume it while discarding the signal.\n\
- \n\
- In a multi-threaded program the signal is queued with, or discarded from,\n\
- the current thread only."));
- set_cmd_completer (c, signal_completer);
- add_com ("stepi", class_run, stepi_command, _("\
- Step one instruction exactly.\n\
- Usage: stepi [N]\n\
- Argument N means step N times (or till program stops for another \
- reason)."));
- add_com_alias ("si", "stepi", class_alias, 0);
- add_com ("nexti", class_run, nexti_command, _("\
- Step one instruction, but proceed through subroutine calls.\n\
- Usage: nexti [N]\n\
- Argument N means step N times (or till program stops for another \
- reason)."));
- add_com_alias ("ni", "nexti", class_alias, 0);
- add_com ("finish", class_run, finish_command, _("\
- Execute until selected stack frame returns.\n\
- Usage: finish\n\
- Upon return, the value returned is printed and put in the value history."));
- add_com_alias ("fin", "finish", class_run, 1);
- add_com ("next", class_run, next_command, _("\
- Step program, proceeding through subroutine calls.\n\
- Usage: next [N]\n\
- Unlike \"step\", if the current source line calls a subroutine,\n\
- this command does not enter the subroutine, but instead steps over\n\
- the call, in effect treating it as a single source line."));
- add_com_alias ("n", "next", class_run, 1);
- if (xdb_commands)
- add_com_alias ("S", "next", class_run, 1);
- add_com ("step", class_run, step_command, _("\
- Step program until it reaches a different source line.\n\
- Usage: step [N]\n\
- Argument N means step N times (or till program stops for another \
- reason)."));
- add_com_alias ("s", "step", class_run, 1);
- c = add_com ("until", class_run, until_command, _("\
- Execute until the program reaches a source line greater than the current\n\
- or a specified location (same args as break command) within the current \
- frame."));
- set_cmd_completer (c, location_completer);
- add_com_alias ("u", "until", class_run, 1);
- c = add_com ("advance", class_run, advance_command, _("\
- Continue the program up to the given location (same form as args for break \
- command).\n\
- Execution will also stop upon exit from the current stack frame."));
- set_cmd_completer (c, location_completer);
- c = add_com ("jump", class_run, jump_command, _("\
- Continue program being debugged at specified line or address.\n\
- Usage: jump <location>\n\
- Give as argument either LINENUM or *ADDR, where ADDR is an expression\n\
- for an address to start at."));
- set_cmd_completer (c, location_completer);
- add_com_alias ("j", "jump", class_run, 1);
- if (xdb_commands)
- {
- c = add_com ("go", class_run, go_command, _("\
- Usage: go <location>\n\
- Continue program being debugged, stopping at specified line or \n\
- address.\n\
- Give as argument either LINENUM or *ADDR, where ADDR is an \n\
- expression for an address to start at.\n\
- This command is a combination of tbreak and jump."));
- set_cmd_completer (c, location_completer);
- }
- if (xdb_commands)
- add_com_alias ("g", "go", class_run, 1);
- add_com ("continue", class_run, continue_command, _("\
- Continue program being debugged, after signal or breakpoint.\n\
- Usage: continue [N]\n\
- If proceeding from breakpoint, a number N may be used as an argument,\n\
- which means to set the ignore count of that breakpoint to N - 1 (so that\n\
- the breakpoint won't break until the Nth time it is reached).\n\
- \n\
- If non-stop mode is enabled, continue only the current thread,\n\
- otherwise all the threads in the program are continued. To \n\
- continue all stopped threads in non-stop mode, use the -a option.\n\
- Specifying -a and an ignore count simultaneously is an error."));
- add_com_alias ("c", "cont", class_run, 1);
- add_com_alias ("fg", "cont", class_run, 1);
- c = add_com ("run", class_run, run_command, _("\
- Start debugged program. You may specify arguments to give it.\n\
- Args may include \"*\", or \"[...]\"; they are expanded using \"sh\".\n\
- Input and output redirection with \">\", \"<\", or \">>\" are also \
- allowed.\n\n\
- With no arguments, uses arguments last specified (with \"run\" \
- or \"set args\").\n\
- To cancel previous arguments and run with no arguments,\n\
- use \"set args\" without arguments."));
- set_cmd_completer (c, filename_completer);
- add_com_alias ("r", "run", class_run, 1);
- if (xdb_commands)
- add_com ("R", class_run, run_no_args_command,
- _("Start debugged program with no arguments."));
- c = add_com ("start", class_run, start_command, _("\
- Run the debugged program until the beginning of the main procedure.\n\
- You may specify arguments to give to your program, just as with the\n\
- \"run\" command."));
- set_cmd_completer (c, filename_completer);
- add_com ("interrupt", class_run, interrupt_command,
- _("Interrupt the execution of the debugged program.\n\
- If non-stop mode is enabled, interrupt only the current thread,\n\
- otherwise all the threads in the program are stopped. To \n\
- interrupt all running threads in non-stop mode, use the -a option."));
- c = add_info ("registers", nofp_registers_info, _("\
- List of integer registers and their contents, for selected stack frame.\n\
- Register name as argument means describe only that register."));
- add_info_alias ("r", "registers", 1);
- set_cmd_completer (c, reg_or_group_completer);
- if (xdb_commands)
- {
- c = add_com ("lr", class_info, nofp_registers_info, _("\
- List of integer registers and their contents, for selected stack frame.\n\
- Register name as argument means describe only that register."));
- set_cmd_completer (c, reg_or_group_completer);
- }
- c = add_info ("all-registers", all_registers_info, _("\
- List of all registers and their contents, for selected stack frame.\n\
- Register name as argument means describe only that register."));
- set_cmd_completer (c, reg_or_group_completer);
- add_info ("program", program_info,
- _("Execution status of the program."));
- add_info ("float", float_info,
- _("Print the status of the floating point unit\n"));
- add_info ("vector", vector_info,
- _("Print the status of the vector unit\n"));
- add_prefix_cmd ("proc", class_info, info_proc_cmd,
- _("\
- Show /proc process information about any running process.\n\
- Specify any process id, or use the program being debugged by default."),
- &info_proc_cmdlist, "info proc ",
- 1, &infolist);
- add_cmd ("mappings", class_info, info_proc_cmd_mappings, _("\
- List of mapped memory regions."),
- &info_proc_cmdlist);
- add_cmd ("stat", class_info, info_proc_cmd_stat, _("\
- List process info from /proc/PID/stat."),
- &info_proc_cmdlist);
- add_cmd ("status", class_info, info_proc_cmd_status, _("\
- List process info from /proc/PID/status."),
- &info_proc_cmdlist);
- add_cmd ("cwd", class_info, info_proc_cmd_cwd, _("\
- List current working directory of the process."),
- &info_proc_cmdlist);
- add_cmd ("cmdline", class_info, info_proc_cmd_cmdline, _("\
- List command line arguments of the process."),
- &info_proc_cmdlist);
- add_cmd ("exe", class_info, info_proc_cmd_exe, _("\
- List absolute filename for executable of the process."),
- &info_proc_cmdlist);
- add_cmd ("all", class_info, info_proc_cmd_all, _("\
- List all available /proc info."),
- &info_proc_cmdlist);
- }