X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Ftop.c;h=93447fe9aa919c9edebf6742b30103ef7a13efb3;hb=0f3bb72eb70f61f3154fd51eaac173bd6486f3d6;hp=9ad2f54a1796347bcda3ec7dbbdfb862823cbc88;hpb=9b254dd1ce46c19dde1dde5b8d1e22e862dfacce;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/top.c b/gdb/top.c index 9ad2f54a17..93447fe9aa 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -2,7 +2,7 @@ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008 Free Software Foundation, Inc. + 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GDB. @@ -46,6 +46,7 @@ #include "gdb_assert.h" #include "main.h" #include "event-loop.h" +#include "gdbthread.h" /* readline include files */ #include "readline/readline.h" @@ -131,9 +132,6 @@ void (*window_hook) (FILE *, char *); int epoch_interface; int xgdb_verbose; -/* gdb prints this when reading a command interactively */ -static char *gdb_prompt_string; /* the global prompt string */ - /* Buffer used for reading command lines, and the size allocated for it so far. */ @@ -181,26 +179,11 @@ int remote_timeout = 2; int remote_debug = 0; -/* Non-zero means the target is running. Note: this is different from - saying that there is an active target and we are stopped at a - breakpoint, for instance. This is a real indicator whether the - target is off and running, which gdb is doing something else. */ -int target_executing = 0; - /* Sbrk location on entry to main. Used for statistics only. */ #ifdef HAVE_SBRK char *lim_at_start; #endif -/* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */ - -#ifndef STOP_SIGNAL -#ifdef SIGTSTP -#define STOP_SIGNAL SIGTSTP -static void stop_sig (int); -#endif -#endif - /* Hooks for alternate command interfaces. */ /* Called after most modules have been initialized, but before taking users @@ -251,13 +234,6 @@ void (*deprecated_readline_begin_hook) (char *, ...); char *(*deprecated_readline_hook) (char *); void (*deprecated_readline_end_hook) (void); -/* Called as appropriate to notify the interface of the specified breakpoint - conditions. */ - -void (*deprecated_create_breakpoint_hook) (struct breakpoint * bpt); -void (*deprecated_delete_breakpoint_hook) (struct breakpoint * bpt); -void (*deprecated_modify_breakpoint_hook) (struct breakpoint * bpt); - /* Called as appropriate to notify the interface that we have attached to or detached from an already running process. */ @@ -274,14 +250,12 @@ void (*deprecated_interactive_hook) (void); that several registers have changed (see value_assign). */ void (*deprecated_register_changed_hook) (int regno); -/* Tell the GUI someone changed LEN bytes of memory at ADDR */ -void (*deprecated_memory_changed_hook) (CORE_ADDR addr, int len); - /* Called when going to wait for the target. Usually allows the GUI to run while waiting for target events. */ ptid_t (*deprecated_target_wait_hook) (ptid_t ptid, - struct target_waitstatus * status); + struct target_waitstatus *status, + int options); /* Used by UI as a wrapper around command execution. May do various things like enabling/disabling buttons, etc... */ @@ -298,11 +272,6 @@ void (*deprecated_set_hook) (struct cmd_list_element * c); void (*deprecated_context_hook) (int id); -/* Takes control from error (). Typically used to prevent longjmps out of the - middle of the GUI. Usually used in conjunction with a catch routine. */ - -void (*deprecated_error_hook) (void); - /* Handler for SIGHUP. */ #ifdef SIGHUP @@ -329,7 +298,7 @@ quit_cover (void *s) /* NOTE 1999-04-29: This variable will be static again, once we modify gdb to use the event loop as the default command loop and we merge event-top.c into this file, top.c */ -/* static */ char *source_file_name; +/* static */ const char *source_file_name; /* Clean up on error during a "source" command (or execution of a user-defined command). */ @@ -364,7 +333,20 @@ do_chdir_cleanup (void *old_dir) } #endif -/* Execute the line P as a command. +void +prepare_execute_command (void) +{ + free_all_values (); + + /* With multiple threads running while the one we're examining is stopped, + the dcache can get stale without us being able to detect it. + For the duration of the command, though, use the dcache to help + things like backtrace. */ + if (non_stop) + target_dcache_invalidate (); +} + +/* Execute the line P as a command, in the current user context. Pass FROM_TTY as second argument to the defining function. */ void @@ -374,8 +356,8 @@ execute_command (char *p, int from_tty) enum language flang; static int warned = 0; char *line; - - free_all_values (); + + prepare_execute_command (); /* Force cleanup of any alloca areas if using C alloca instead of a builtin alloca. */ @@ -399,15 +381,6 @@ execute_command (char *p, int from_tty) c = lookup_cmd (&p, cmdlist, "", 0, 1); - /* If the target is running, we allow only a limited set of - commands. */ - if (target_can_async_p () && target_executing) - if (strcmp (c->name, "help") != 0 - && strcmp (c->name, "pwd") != 0 - && strcmp (c->name, "show") != 0 - && strcmp (c->name, "stop") != 0) - error (_("Cannot execute this command while the target is running.")); - /* Pass null arg rather than an empty one. */ arg = *p ? p : 0; @@ -453,10 +426,13 @@ execute_command (char *p, int from_tty) } - /* Tell the user if the language has changed (except first time). */ + /* Tell the user if the language has changed (except first time). + First make sure that a new frame has been selected, in case this + command or the hooks changed the program state. */ + deprecated_safe_get_selected_frame (); if (current_language != expected_language) { - if (language_mode == language_mode_auto) + if (language_mode == language_mode_auto && info_verbose) { language_info (1); /* Print what changed. */ } @@ -469,7 +445,7 @@ execute_command (char *p, int from_tty) /* FIXME: This should be cacheing the frame and only running when the frame changes. */ - if (target_has_stack) + if (has_stack_frames ()) { flang = get_frame_language (); if (!warned @@ -491,12 +467,6 @@ command_loop (void) struct cleanup *old_chain; char *command; int stdin_is_tty = ISATTY (stdin); - long time_at_cmd_start; -#ifdef HAVE_SBRK - long space_at_cmd_start = 0; -#endif - extern int display_time; - extern int display_space; while (instream && !feof (instream)) { @@ -515,75 +485,12 @@ command_loop (void) if (command == 0) return; - time_at_cmd_start = get_run_time (); - - if (display_space) - { -#ifdef HAVE_SBRK - char *lim = (char *) sbrk (0); - space_at_cmd_start = lim - lim_at_start; -#endif - } + make_command_stats_cleanup (1); execute_command (command, instream == stdin); - /* Do any commands attached to breakpoint we stopped at. */ - bpstat_do_actions (&stop_bpstat); - do_cleanups (old_chain); - if (display_time) - { - long cmd_time = get_run_time () - time_at_cmd_start; - - printf_unfiltered (_("Command execution time: %ld.%06ld\n"), - cmd_time / 1000000, cmd_time % 1000000); - } - - if (display_space) - { -#ifdef HAVE_SBRK - char *lim = (char *) sbrk (0); - long space_now = lim - lim_at_start; - long space_diff = space_now - space_at_cmd_start; - - printf_unfiltered (_("Space used: %ld (%s%ld for this command)\n"), - space_now, - (space_diff >= 0 ? "+" : ""), - space_diff); -#endif - } - } -} - -/* Read commands from `instream' and execute them until end of file or - error reading instream. This command loop doesnt care about any - such things as displaying time and space usage. If the user asks - for those, they won't work. */ -void -simplified_command_loop (char *(*read_input_func) (char *), - void (*execute_command_func) (char *, int)) -{ - struct cleanup *old_chain; - char *command; - int stdin_is_tty = ISATTY (stdin); - - while (instream && !feof (instream)) - { - quit_flag = 0; - if (instream == stdin && stdin_is_tty) - reinitialize_more_filter (); - old_chain = make_cleanup (null_cleanup, 0); - - /* Get a command-line. */ - command = (*read_input_func) (instream == stdin ? - get_prompt () : (char *) NULL); - - if (command == 0) - return; - - (*execute_command_func) (command, instream == stdin); - - /* Do any commands attached to breakpoint we stopped at. */ - bpstat_do_actions (&stop_bpstat); + /* Do any commands attached to breakpoint we are stopped at. */ + bpstat_do_actions (); do_cleanups (old_chain); } @@ -814,57 +721,6 @@ gdb_readline_wrapper (char *prompt) } -#ifdef STOP_SIGNAL -static void -stop_sig (int signo) -{ -#if STOP_SIGNAL == SIGTSTP - signal (SIGTSTP, SIG_DFL); -#if HAVE_SIGPROCMASK - { - sigset_t zero; - - sigemptyset (&zero); - sigprocmask (SIG_SETMASK, &zero, 0); - } -#elif HAVE_SIGSETMASK - sigsetmask (0); -#endif - kill (getpid (), SIGTSTP); - signal (SIGTSTP, stop_sig); -#else - signal (STOP_SIGNAL, stop_sig); -#endif - printf_unfiltered ("%s", get_prompt ()); - gdb_flush (gdb_stdout); - - /* Forget about any previous command -- null line now will do nothing. */ - dont_repeat (); -} -#endif /* STOP_SIGNAL */ - -/* Initialize signal handlers. */ -static void -float_handler (int signo) -{ - /* This message is based on ANSI C, section 4.7. Note that integer - divide by zero causes this, so "float" is a misnomer. */ - signal (SIGFPE, float_handler); - error (_("Erroneous arithmetic operation.")); -} - -static void -do_nothing (int signo) -{ - /* Under System V the default disposition of a signal is reinstated after - the signal is caught and delivered to an application process. On such - systems one must restore the replacement signal handler if one wishes - to continue handling the signal in one's program. On BSD systems this - is not needed but it is harmless, and it simplifies the code to just do - it unconditionally. */ - signal (signo, do_nothing); -} - /* The current saved history number from operate-and-get-next. This is -1 if not valid. */ static int operate_saved_history = -1; @@ -875,6 +731,7 @@ static void gdb_rl_operate_and_get_next_completion (void) { int delta = where_history () - operate_saved_history; + /* The `key' argument to rl_get_previous_history is ignored. */ rl_get_previous_history (delta, 0); operate_saved_history = -1; @@ -1143,11 +1000,11 @@ print_gdb_version (struct ui_file *stream) program to parse, and is just canonical program name and version number, which starts after last space. */ - fprintf_filtered (stream, "GNU gdb %s\n", version); + fprintf_filtered (stream, "GNU gdb %s%s\n", PKGVERSION, version); /* Second line is a copyright notice. */ - fprintf_filtered (stream, "Copyright (C) 2008 Free Software Foundation, Inc.\n"); + fprintf_filtered (stream, "Copyright (C) 2010 Free Software Foundation, Inc.\n"); /* Following the copyright is a brief statement that the program is free software, that users are free to copy and change it on @@ -1172,6 +1029,13 @@ and \"show warranty\" for details.\n"); fprintf_filtered (stream, "%s", host_name); } fprintf_filtered (stream, "\"."); + + if (REPORT_BUGS_TO[0]) + { + fprintf_filtered (stream, + _("\nFor bug reporting instructions, please see:\n")); + fprintf_filtered (stream, "%s.", REPORT_BUGS_TO); + } } /* get_prompt: access method for the GDB prompt string. */ @@ -1186,64 +1050,127 @@ void set_prompt (char *s) { /* ??rehrauer: I don't know why this fails, since it looks as though - assignments to prompt are wrapped in calls to savestring... + assignments to prompt are wrapped in calls to xstrdup... if (prompt != NULL) xfree (prompt); */ - PROMPT (0) = savestring (s, strlen (s)); + PROMPT (0) = xstrdup (s); } +struct qt_args +{ + char *args; + int from_tty; +}; + +/* Callback for iterate_over_inferiors. Kills or detaches the given + inferior, depending on how we originally gained control of it. */ + +static int +kill_or_detach (struct inferior *inf, void *args) +{ + struct qt_args *qt = args; + struct thread_info *thread; + + if (inf->pid == 0) + return 0; + + thread = any_thread_of_process (inf->pid); + if (thread != NULL) + { + switch_to_thread (thread->ptid); + + /* Leave core files alone. */ + if (target_has_execution) + { + if (inf->attach_flag) + target_detach (qt->args, qt->from_tty); + else + target_kill (); + } + } + + return 0; +} + +/* Callback for iterate_over_inferiors. Prints info about what GDB + will do to each inferior on a "quit". ARG points to a struct + ui_out where output is to be collected. */ + +static int +print_inferior_quit_action (struct inferior *inf, void *arg) +{ + struct ui_file *stb = arg; + + if (inf->pid == 0) + return 0; + + if (inf->attach_flag) + fprintf_filtered (stb, + _("\tInferior %d [%s] will be detached.\n"), inf->num, + target_pid_to_str (pid_to_ptid (inf->pid))); + else + fprintf_filtered (stb, + _("\tInferior %d [%s] will be killed.\n"), inf->num, + target_pid_to_str (pid_to_ptid (inf->pid))); + + return 0; +} + /* If necessary, make the user confirm that we should quit. Return non-zero if we should quit, zero if we shouldn't. */ int quit_confirm (void) { - if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution) - { - char *s; - - /* This is something of a hack. But there's no reliable way to - see if a GUI is running. The `use_windows' variable doesn't - cut it. */ - if (deprecated_init_ui_hook) - s = "A debugging session is active.\nDo you still want to close the debugger?"; - else if (attach_flag) - s = "The program is running. Quit anyway (and detach it)? "; - else - s = "The program is running. Exit anyway? "; + struct ui_file *stb; + struct cleanup *old_chain; + char *str; + int qr; + + /* Don't even ask if we're only debugging a core file inferior. */ + if (!have_live_inferiors ()) + return 1; - if (!query ("%s", s)) - return 0; + /* Build the query string as a single string. */ + stb = mem_fileopen (); + old_chain = make_cleanup_ui_file_delete (stb); + + /* This is something of a hack. But there's no reliable way to see + if a GUI is running. The `use_windows' variable doesn't cut + it. */ + if (deprecated_init_ui_hook) + fprintf_filtered (stb, _("A debugging session is active.\n" + "Do you still want to close the debugger?")); + else + { + fprintf_filtered (stb, _("A debugging session is active.\n\n")); + iterate_over_inferiors (print_inferior_quit_action, stb); + fprintf_filtered (stb, _("\nQuit anyway? ")); } - return 1; + str = ui_file_xstrdup (stb, NULL); + make_cleanup (xfree, str); + + qr = query ("%s", str); + do_cleanups (old_chain); + return qr; } /* Helper routine for quit_force that requires error handling. */ -struct qt_args -{ - char *args; - int from_tty; -}; - static int quit_target (void *arg) { struct qt_args *qt = (struct qt_args *)arg; - if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution) - { - if (attach_flag) - target_detach (qt->args, qt->from_tty); - else - target_kill (); - } + /* Kill or detach all inferiors. */ + iterate_over_inferiors (kill_or_detach, qt); - /* UDI wants this, to kill the TIP. */ - target_close (¤t_target, 1); + /* Give all pushed targets a chance to do minimal cleanup, and pop + them all out. */ + pop_all_targets (1); /* Save the history information if it is appropriate to do so. */ if (write_history_p && history_filename) @@ -1283,12 +1210,38 @@ quit_force (char *args, int from_tty) exit (exit_code); } +/* If OFF, the debugger will run in non-interactive mode, which means + that it will automatically select the default answer to all the + queries made to the user. If ON, gdb will wait for the user to + answer all queries. If AUTO, gdb will determine whether to run + in interactive mode or not depending on whether stdin is a terminal + or not. */ +static enum auto_boolean interactive_mode = AUTO_BOOLEAN_AUTO; + +/* Implement the "show interactive-mode" option. */ + +static void +show_interactive_mode (struct ui_file *file, int from_tty, + struct cmd_list_element *c, + const char *value) +{ + if (interactive_mode == AUTO_BOOLEAN_AUTO) + fprintf_filtered (file, "\ +Debugger's interactive mode is %s (currently %s).\n", + value, input_from_terminal_p () ? "on" : "off"); + else + fprintf_filtered (file, "Debugger's interactive mode is %s.\n", value); +} + /* Returns whether GDB is running on a terminal and input is currently coming from that terminal. */ int input_from_terminal_p (void) { + if (interactive_mode != AUTO_BOOLEAN_AUTO) + return interactive_mode == AUTO_BOOLEAN_TRUE; + if (gdb_has_a_terminal () && instream == stdin) return 1; @@ -1457,7 +1410,7 @@ init_history (void) tmpenv = getenv ("GDBHISTFILE"); if (tmpenv) - history_filename = savestring (tmpenv, strlen (tmpenv)); + history_filename = xstrdup (tmpenv); else if (!history_filename) { /* We include the current directory so that if the user changes @@ -1509,19 +1462,17 @@ Notification of completion for asynchronous execution commands is %s.\n"), static void init_main (void) { - struct cmd_list_element *c; - /* initialize the prompt stack to a simple "(gdb) " prompt or to whatever the DEFAULT_PROMPT is. */ the_prompts.top = 0; PREFIX (0) = ""; - PROMPT (0) = savestring (DEFAULT_PROMPT, strlen (DEFAULT_PROMPT)); + PROMPT (0) = xstrdup (DEFAULT_PROMPT); SUFFIX (0) = ""; /* Set things up for annotation_level > 1, if the user ever decides to use it. */ async_annotation_suffix = "prompt"; /* Set the variable associated with the setshow prompt command. */ - new_async_prompt = savestring (PROMPT (0), strlen (PROMPT (0))); + new_async_prompt = xstrdup (PROMPT (0)); /* If gdb was started with --annotate=2, this is equivalent to the user entering the command 'set annotate 2' at the gdb prompt, so @@ -1535,6 +1486,7 @@ init_main (void) write_history_p = 0; /* Setup important stuff for command line editing. */ + rl_completion_word_break_hook = gdb_completion_word_break_characters; rl_completion_entry_function = readline_line_completion_function; rl_completer_word_break_characters = default_word_break_characters (); rl_completer_quote_characters = get_gdb_completer_quote_characters (); @@ -1618,6 +1570,27 @@ Use \"on\" to enable the notification, and \"off\" to disable it."), NULL, show_exec_done_display_p, &setlist, &showlist); + + add_setshow_auto_boolean_cmd ("interactive-mode", class_support, + &interactive_mode, _("\ +Set whether GDB should run in interactive mode or not"), _("\ +Show whether GDB runs in interactive mode"), _("\ +If on, run in interactive mode and wait for the user to answer\n\ +all queries. If off, run in non-interactive mode and automatically\n\ +assume the default answer to all queries. If auto (the default),\n\ +determine which mode to use based on the standard input settings"), + NULL, + show_interactive_mode, + &setlist, &showlist); + + add_setshow_filename_cmd ("data-directory", class_maintenance, + &gdb_datadir, _("Set GDB's data directory."), + _("Show GDB's data directory."), + _("\ +When set, GDB uses the specified path to search for data files."), + NULL, NULL, + &setlist, + &showlist); } void @@ -1628,9 +1601,6 @@ gdb_init (char *argv0) /* Run the init function of each source file */ - getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); - current_directory = gdb_dirbuf; - #ifdef __MSDOS__ /* Make sure we return to the original directory upon exit, come what may, since the OS doesn't do that for us. */ @@ -1641,6 +1611,13 @@ gdb_init (char *argv0) initialize_targets (); /* Setup target_terminal macros for utils.c */ initialize_utils (); /* Make errors and warnings possible */ initialize_all_files (); + /* This creates the current_program_space. Do this after all the + _initialize_foo routines have had a chance to install their + per-sspace data keys. Also do this before + initialize_current_architecture is called, because it accesses + exec_bfd of the current program space. */ + initialize_progspace (); + initialize_inferiors (); initialize_current_architecture (); init_cli_cmds(); init_main (); /* But that omits this file! Do it now */