diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 6bc621dbd7..97080fff8d 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -50,7 +50,7 @@ static int executing_breakpoint_commands; enum enable { disabled, enabled, temporary, delete}; /* Not that the ->silent field is not currently used by any commands - (though the code is in there if it was to be and set_raw_breakpoint + (though the code is in there if it was to be, and set_raw_breakpoint does set it to 0). I implemented it because I thought it would be useful for a hack I had to put in; I'm going to leave it in because I can see how there might be times when it would indeed be useful */ @@ -825,10 +825,10 @@ breakpoint_1 (bnum, watchpoints) } printf_filtered ("#%-3d %c ", b->number, "nyod"[(int) b->enable]); - if (b->address == NULL) + if (b->address == NULL) { + printf_filtered (" "); print_expression (b->exp, stdout); - else - { + } else { if (addressprint) printf_filtered (" 0x%08x ", b->address); @@ -967,6 +967,9 @@ check_duplicates (address) register struct breakpoint *b; register int count = 0; + if (address == NULL) /* Watchpoints are uninteresting */ + return; + ALL_BREAKPOINTS (b) if (b->enable != disabled && b->address == address) { @@ -979,7 +982,11 @@ check_duplicates (address) Takes as args the three things that every breakpoint must have. Returns the breakpoint object so caller can set other things. Does not set the breakpoint number! - Does not print anything. */ + Does not print anything. + + ==> This routine should not be called if there is a chance of later + error(); otherwise it leaves a bogus breakpoint on the chain. Validate + your arguments BEFORE calling this routine! */ static struct breakpoint * set_raw_breakpoint (sal) @@ -1260,19 +1267,28 @@ watch_command (arg, from_tty) { struct breakpoint *b; struct symtab_and_line sal; + struct expression *exp; + struct block *exp_valid_block; + struct value *val; sal.pc = NULL; sal.symtab = NULL; sal.line = 0; + /* Parse arguments. */ + innermost_block = NULL; + exp = parse_c_expression (arg); + exp_valid_block = innermost_block; + val = evaluate_expression (exp); + release_value (val); + + /* Now set up the breakpoint. */ b = set_raw_breakpoint (sal); set_breakpoint_count (breakpoint_count + 1); b->number = breakpoint_count; - innermost_block = NULL; - b->exp = parse_c_expression (arg); - b->exp_valid_block = innermost_block; - b->val = evaluate_expression (b->exp); - release_value (b->val); + b->exp = exp; + b->exp_valid_block = exp_valid_block; + b->val = val; b->cond = 0; b->cond_string = NULL; mention (b); @@ -1986,6 +2002,15 @@ enable_breakpoint (bpt) check_duplicates (bpt->address); if (bpt->val != NULL) { + if (bpt->exp_valid_block != NULL + && !contained_in (get_selected_block (), bpt->exp_valid_block)) + { + printf_filtered ("\ +Cannot enable watchpoint %d because the block in which its expression\n\ +is valid is not currently in scope.\n", bpt->number); + return; + } + value_free (bpt->val); bpt->val = evaluate_expression (bpt->exp); @@ -2189,7 +2214,6 @@ Also a prefix command for deletion of other GDB objects.\n\ The \"unset\" command is also an alias for \"delete\".", &deletelist, "delete ", 1, &cmdlist); add_com_alias ("d", "delete", class_breakpoint, 1); - add_com_alias ("unset", "delete", class_alias, 1); add_cmd ("breakpoints", class_alias, delete_command, "Delete some breakpoints or auto-display expressions.\n\ diff --git a/gdb/infcmd.c b/gdb/infcmd.c index e3f86d4747..25883a0a93 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -915,6 +915,7 @@ attach_command (args, from_tty) char *args; int from_tty; { + dont_repeat (); /* Not for the faint of heart */ target_attach (args, from_tty); } @@ -934,6 +935,7 @@ detach_command (args, from_tty) char *args; int from_tty; { + dont_repeat (); /* Not for the faint of heart */ target_detach (args, from_tty); } @@ -949,6 +951,18 @@ float_info (addr_exp) #endif } +struct cmd_list_element *unsetlist = NULL; + +/* ARGSUSED */ +static void +unset_command (args, from_tty) + char *args; + int from_tty; +{ + printf ("\"unset\" must be followed by the name of an unset subcommand.\n"); + help_list (unsetlist, "unset ", -1, stdout); +} + void _initialize_infcmd () { @@ -973,10 +987,14 @@ give the program being debugged. With no arguments, prints the entire\n\ environment to be given to the program.", &showlist); c->completer = 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.", - &deletelist); + &unsetlist); c->completer = noop_completer; c = add_cmd ("environment", class_run, set_environment_command, diff --git a/gdb/main.c b/gdb/main.c index 5845079f20..34640da84f 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -68,6 +68,8 @@ int original_stack_limit; #endif char gdbinit[] = GDBINIT_FILENAME; +#define ALL_CLEANUPS ((struct cleanup *)0) + /* Version number of GDB, as a string. */ extern char *version; @@ -206,7 +208,7 @@ return_to_top_level () bpstat_clear_actions(stop_bpstat); /* Clear queued breakpoint commands */ clear_momentary_breakpoints (); disable_current_display (); - do_cleanups (0); + do_cleanups (ALL_CLEANUPS); longjmp (to_top_level, 1); } @@ -536,10 +538,14 @@ GDB manual (available as on-line info or a printed manual).\n", stderr); init_source_path (); } } + do_cleanups (ALL_CLEANUPS); + for (i = 0; i < ndir; i++) if (!setjmp (to_top_level)) directory_command (dirarg[i], 0); free (dirarg); + do_cleanups (ALL_CLEANUPS); + if (execarg != NULL && symarg != NULL && strcmp (execarg, symarg) == 0) @@ -561,15 +567,19 @@ GDB manual (available as on-line info or a printed manual).\n", stderr); if (!setjmp (to_top_level)) symbol_file_command (symarg, !batch); } + do_cleanups (ALL_CLEANUPS); + if (corearg != NULL) if (!setjmp (to_top_level)) core_file_command (corearg, !batch); else if (!setjmp (to_top_level)) attach_command (corearg, !batch); + do_cleanups (ALL_CLEANUPS); if (ttyarg != NULL) if (!setjmp (to_top_level)) tty_command (ttyarg, !batch); + do_cleanups (ALL_CLEANUPS); #ifdef ADDITIONAL_OPTION_HANDLER ADDITIONAL_OPTION_HANDLER; @@ -591,6 +601,7 @@ GDB manual (available as on-line info or a printed manual).\n", stderr); if (!inhibit_gdbinit && access (homeinit, R_OK) == 0) if (!setjmp (to_top_level)) source_command (homeinit, 0); + do_cleanups (ALL_CLEANUPS); /* Do stats; no need to do them elsewhere since we'll only need them if homedir is set. Make sure that they are @@ -615,6 +626,7 @@ GDB manual (available as on-line info or a printed manual).\n", stderr); if (!inhibit_gdbinit && access (gdbinit, R_OK) == 0) if (!setjmp (to_top_level)) source_command (gdbinit, 0); + do_cleanups (ALL_CLEANUPS); } for (i = 0; i < ncmd; i++) @@ -624,6 +636,7 @@ GDB manual (available as on-line info or a printed manual).\n", stderr); read_command_file (stdin); else source_command (cmdarg[i], !batch); + do_cleanups (ALL_CLEANUPS); } free (cmdarg); @@ -646,6 +659,7 @@ GDB manual (available as on-line info or a printed manual).\n", stderr); { if (!setjmp (to_top_level)) { + do_cleanups (ALL_CLEANUPS); /* Do complete cleanup */ command_loop (); quit_command ((char *)0, instream == stdin); } @@ -710,8 +724,8 @@ execute_command (p, from_tty) } /* ARGSUSED */ -static void -do_nothing (foo) +void +command_loop_marker (foo) int foo; { } @@ -733,7 +747,7 @@ command_loop () quit_flag = 0; if (instream == stdin && stdin_is_tty) reinitialize_more_filter (); - old_chain = make_cleanup (do_nothing, 0); + old_chain = make_cleanup (command_loop_marker, 0); command = command_line_input (instream == stdin ? prompt : 0, instream == stdin); if (command == 0) @@ -1055,6 +1069,11 @@ catch_termination (sig) #endif /* Initialize signal handlers. */ +static void +do_nothing () +{ +} + static void init_signals () { @@ -1557,7 +1576,7 @@ GDB is free software and you are welcome to distribute copies of it\n\ } static void -version_info (args, from_tty) +show_version (args, from_tty) char *args; int from_tty; { @@ -1580,7 +1599,7 @@ quit_command (args, from_tty) char *args; int from_tty; { - if (inferior_pid != 0) + if (inferior_pid != 0 && target_has_execution) { if (query ("The program is running. Quit anyway? ")) { @@ -1731,6 +1750,7 @@ echo_command (text, from_tty) else fputc (c, stdout); } + fflush (stdout); } /* ARGSUSED */ @@ -1748,10 +1768,10 @@ dump_me_command (args, from_tty) /* Functions to manipulate command line editing control variables. */ -/* Number of commands to print in each call to editing_info. */ +/* Number of commands to print in each call to show_commands. */ #define Hist_print 10 static void -editing_info (args, from_tty) +show_commands (args, from_tty) char *args; int from_tty; { @@ -1878,7 +1898,7 @@ show_history (args, from_tty) char *args; int from_tty; { - cmd_show_list (showhistlist, from_tty); + cmd_show_list (showhistlist, from_tty, ""); } int info_verbose = 0; /* Default verbose msgs off */ @@ -2084,7 +2104,7 @@ Without an argument, history expansion is enabled.", &sethistlist), &showhistlist); add_show_from_set - (add_set_cmd ("write", no_class, var_boolean, (char *)&write_history_p, + (add_set_cmd ("save", no_class, var_boolean, (char *)&write_history_p, "Set saving of the history record on exit.\n\ Use \"on\" to enable to enable the saving, and \"off\" to disable it.\n\ Without an argument, saving is enabled.", &sethistlist), @@ -2103,11 +2123,10 @@ ie. the number of previous commands to keep a record of.", &sethistlist); &showhistlist); add_show_from_set - (add_set_cmd ("caution", class_support, var_boolean, + (add_set_cmd ("confirm", class_support, var_boolean, (char *)&caution, - "Set expected caution of user.\n\ -If on (the default), more warnings are printed, and the user is asked whether\n\ -they really want to do various major commands.", &setlist), + "Set whether to confirm potentially dangerous operations.", + &setlist), &showlist); add_prefix_cmd ("info", class_info, info_command, @@ -2121,7 +2140,9 @@ they really want to do various major commands.", &setlist), /* Another way to get at the same thing. */ add_info ("set", show_command, "Show all GDB settings."); - add_info ("editing", editing_info, "Status of command editor."); + add_cmd ("commands", no_class, show_commands, "Status of command editor.", + &showlist); - add_info ("version", version_info, "Report what version of GDB this is."); + add_cmd ("version", no_class, show_version, + "Report what version of GDB this is.", &showlist); } diff --git a/gdb/utils.c b/gdb/utils.c index 1441db12e5..b3af85d9a4 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -272,6 +272,7 @@ void init_malloc () { mcheck (malloc_botch); + mtrace (); } #endif /* Have mcheck(). */ @@ -1275,20 +1276,20 @@ _initialize_utils () (add_set_cmd ("demangle", class_support, var_boolean, (char *)&demangle, "Set demangling of encoded C++ names when displaying symbols.", - &setlist), - &showlist); + &setprintlist), + &showprintlist); add_show_from_set (add_set_cmd ("sevenbit-strings", class_support, var_boolean, (char *)&sevenbit_strings, "Set printing of 8-bit characters in strings as \\nnn.", - &setlist), - &showlist); + &setprintlist), + &showprintlist); add_show_from_set (add_set_cmd ("asm-demangle", class_support, var_boolean, (char *)&asm_demangle, "Set demangling of C++ names in disassembly listings.", - &setlist), - &showlist); + &setprintlist), + &showprintlist); } diff --git a/gdb/valprint.c b/gdb/valprint.c index 9a3ab9055f..58d53690c8 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -505,19 +505,14 @@ val_print_fields (type, valaddr, stream, format, recurse, pretty, dont_print) } if (TYPE_FIELD_PACKED (type, i)) { - LONGEST val; - char *valp = (char *) & val; + value v; - val = unpack_field_as_long (type, valaddr, i); + /* Bitfields require special handling, especially due to byte + order problems. */ + v = value_from_long (TYPE_FIELD_TYPE (type, i), + unpack_field_as_long (type, valaddr, i)); - /* Since we have moved the bitfield into a long, - if it is declared with a smaller type, we need to - offset its address *in gdb* to match the type we - are passing to val_print. */ -#if HOST_BYTE_ORDER == BIG_ENDIAN - valp += sizeof val - TYPE_LENGTH (TYPE_FIELD_TYPE (type, i)); -#endif - val_print (TYPE_FIELD_TYPE (type, i), valp, 0, + val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0, stream, format, 0, recurse + 1, pretty); } else @@ -1805,49 +1800,77 @@ set_radix (arg, from_tty, c) set_output_radix (arg, 0, c); } +struct cmd_list_element *setprintlist = NULL; +struct cmd_list_element *showprintlist = NULL; + +/*ARGSUSED*/ +static void +set_print (arg, from_tty) + char *arg; + int from_tty; +{ + printf ( +"\"set print\" must be followed by the name of a print subcommand.\n"); + help_list (setprintlist, "set print ", -1, stdout); +} + +/*ARGSUSED*/ +static void +show_print (args, from_tty) + char *args; + int from_tty; +{ + cmd_show_list (showprintlist, from_tty, ""); +} + void _initialize_valprint () { struct cmd_list_element *c; + add_prefix_cmd ("print", no_class, set_print, + "Generic command for setting how things print.", + &setprintlist, "set print ", 0, &setlist); + add_prefix_cmd ("print", no_class, show_print, + "Generic command for showing print settings.", + &showprintlist, "show print ", 0, &showlist); + add_show_from_set - (add_set_cmd ("array-max", class_vars, var_uinteger, (char *)&print_max, + (add_set_cmd ("elements", no_class, var_uinteger, (char *)&print_max, "Set limit on string chars or array elements to print.\n\ -\"set array-max 0\" causes there to be no limit.", - &setlist), - &showlist); +\"set print elements 0\" causes there to be no limit.", + &setprintlist), + &showprintlist); add_show_from_set - (add_set_cmd ("prettyprint", class_support, var_boolean, (char *)&prettyprint, + (add_set_cmd ("pretty", class_support, var_boolean, (char *)&prettyprint, "Set prettyprinting of structures.", - &setlist), - &showlist); - - add_alias_cmd ("pp", "prettyprint", class_support, 1, &setlist); + &setprintlist), + &showprintlist); add_show_from_set - (add_set_cmd ("unionprint", class_support, var_boolean, (char *)&unionprint, + (add_set_cmd ("union", class_support, var_boolean, (char *)&unionprint, "Set printing of unions interior to structures.", - &setlist), - &showlist); + &setprintlist), + &showprintlist); add_show_from_set - (add_set_cmd ("vtblprint", class_support, var_boolean, (char *)&vtblprint, + (add_set_cmd ("vtbl", class_support, var_boolean, (char *)&vtblprint, "Set printing of C++ virtual function tables.", - &setlist), - &showlist); + &setprintlist), + &showprintlist); add_show_from_set - (add_set_cmd ("arrayprint", class_support, var_boolean, (char *)&arrayprint, + (add_set_cmd ("array", class_support, var_boolean, (char *)&arrayprint, "Set prettyprinting of arrays.", - &setlist), - &showlist); + &setprintlist), + &showprintlist); add_show_from_set - (add_set_cmd ("addressprint", class_support, var_boolean, (char *)&addressprint, + (add_set_cmd ("address", class_support, var_boolean, (char *)&addressprint, "Set printing of addresses.", - &setlist), - &showlist); + &setprintlist), + &showprintlist); #if 0 /* The "show radix" cmd isn't good enough to show two separate values. diff --git a/gdb/values.c b/gdb/values.c index 5d40882646..196ea23b37 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -26,6 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "gdbcore.h" #include "frame.h" #include "command.h" +#include "gdbcmd.h" /* The value-history records all the values printed by print commands during this session. Each chunk @@ -286,7 +287,7 @@ clear_value_history () } static void -value_history_info (num_exp, from_tty) +show_values (num_exp, from_tty) char *num_exp; int from_tty; { @@ -446,7 +447,7 @@ clear_internalvars () } static void -convenience_info () +show_convenience () { register struct internalvar *var; int varseen = 0; @@ -1331,15 +1332,16 @@ set_return_value (val) void _initialize_values () { - add_info ("convenience", convenience_info, + add_cmd ("convenience", no_class, show_convenience, "Debugger convenience (\"$foo\") variables.\n\ These variables are created when you assign them values;\n\ thus, \"print $foo=1\" gives \"$foo\" the value 1. Values may be any type.\n\n\ A few convenience variables are given values automatically:\n\ \"$_\"holds the last address examined with \"x\" or \"info lines\",\n\ -\"$__\" holds the contents of the last address examined with \"x\"."); +\"$__\" holds the contents of the last address examined with \"x\".", + &showlist); - add_info ("values", value_history_info, - "Elements of value history around item number IDX (or last ten)."); - add_info_alias ("history", "values", 0); + add_cmd ("values", no_class, show_values, + "Elements of value history around item number IDX (or last ten).", + &showlist); }