Index: inferior.h =================================================================== RCS file: /cvs/src/src/gdb/inferior.h,v retrieving revision 1.143 diff -p -r1.143 inferior.h *** inferior.h 25 Mar 2010 20:48:53 -0000 1.143 --- inferior.h 3 Jun 2010 23:44:48 -0000 *************** extern int number_of_inferiors (void); *** 628,631 **** --- 628,633 ---- extern struct inferior *add_inferior_with_spaces (void); + extern void update_observer_mode (void); + #endif /* !defined (INFERIOR_H) */ Index: infrun.c =================================================================== RCS file: /cvs/src/src/gdb/infrun.c,v retrieving revision 1.441 diff -p -r1.441 infrun.c *** infrun.c 17 May 2010 10:40:06 -0000 1.441 --- infrun.c 3 Jun 2010 23:44:48 -0000 *************** show_debug_infrun (struct ui_file *file, *** 178,183 **** --- 178,262 ---- #define SOLIB_IN_DYNAMIC_LINKER(pid,pc) 0 #endif + /* "Observer mode" is somewhat like a more extreme version of + non-stop, in which all GDB operations that might affect the + target's execution have been disabled. */ + + static int non_stop_1 = 0; + + int observer_mode = 0; + static int observer_mode_1 = 0; + + static void + set_observer_mode (char *args, int from_tty, + struct cmd_list_element *c) + { + extern int pagination_enabled; + + if (target_has_execution) + { + observer_mode_1 = observer_mode; + error (_("Cannot change this setting while the inferior is running.")); + } + + observer_mode = observer_mode_1; + + may_write_registers = !observer_mode; + may_write_memory = !observer_mode; + may_insert_breakpoints = !observer_mode; + may_insert_tracepoints = !observer_mode; + /* We can insert fast tracepoints in or out of observer mode, + but enable them if we're going into this mode. */ + if (observer_mode) + may_insert_fast_tracepoints = 1; + may_stop = !observer_mode; + update_target_permissions (); + + /* Going *into* observer mode we must force non-stop, then + going out we leave it that way. */ + if (observer_mode) + { + target_async_permitted = 1; + pagination_enabled = 0; + non_stop = non_stop_1 = 1; + } + + if (from_tty) + printf_filtered (_("Observer mode is now %s.\n"), + (observer_mode ? "on" : "off")); + } + + static void + show_observer_mode (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) + { + fprintf_filtered (file, _("Observer mode is %s.\n"), value); + } + + /* This updates the value of observer mode based on changes in + permissions. Note that we are deliberately ignoring the values of + may-write-registers and may-write-memory, since the user may have + reason to enable these during a session, for instance to turn on a + debugging-related global. */ + + void + update_observer_mode (void) + { + int newval; + + newval = (!may_insert_breakpoints + && !may_insert_tracepoints + && may_insert_fast_tracepoints + && !may_stop + && non_stop); + + /* Let the user know if things change. */ + if (newval != observer_mode) + printf_filtered (_("Observer mode is now %s.\n"), + (newval ? "on" : "off")); + + observer_mode = observer_mode_1 = newval; + } /* Tables of how to react to signals; the user sets them. */ *************** show_exec_direction_func (struct ui_file *** 6423,6429 **** /* User interface for non-stop mode. */ int non_stop = 0; - static int non_stop_1 = 0; static void set_non_stop (char *args, int from_tty, --- 6502,6507 ---- *************** Tells gdb whether to detach the child of *** 6725,6728 **** --- 6803,6819 ---- isn't initialized yet. At this point, we're quite sure there isn't another convenience variable of the same name. */ create_internalvar_type_lazy ("_siginfo", siginfo_make_value); + + add_setshow_boolean_cmd ("observer", no_class, + &observer_mode_1, _("\ + Set whether gdb controls the inferior in observer mode."), _("\ + Show whether gdb controls the inferior in observer mode."), _("\ + In observer mode, GDB can get data from the inferior, but not\n\ + affect its execution. Registers and memory may not be changed,\n\ + breakpoints may not be set, and the program cannot be interrupted\n\ + or signalled."), + set_observer_mode, + show_observer_mode, + &setlist, + &showlist); } Index: remote.c =================================================================== RCS file: /cvs/src/src/gdb/remote.c,v retrieving revision 1.415 diff -p -r1.415 remote.c *** remote.c 2 Jun 2010 22:21:53 -0000 1.415 --- remote.c 3 Jun 2010 23:44:49 -0000 *************** static void show_remote_protocol_packet_ *** 212,217 **** --- 212,219 ---- static char *write_ptid (char *buf, const char *endbuf, ptid_t ptid); static ptid_t read_ptid (char *buf, char **obuf); + static void remote_set_permissions (void); + struct remote_state; static int remote_get_trace_status (struct trace_status *ts); *************** enum { *** 1213,1218 **** --- 1215,1221 ---- PACKET_bc, PACKET_bs, PACKET_TracepointSource, + PACKET_QAllow, PACKET_MAX }; *************** remote_start_remote (struct ui_out *uiou *** 3046,3051 **** --- 3049,3058 ---- which later probes to skip. */ remote_query_supported (); + /* If the stub wants to get a QAllow, compose one and send it. */ + if (remote_protocol_packets[PACKET_QAllow].support != PACKET_DISABLE) + remote_set_permissions (); + /* Next, we possibly activate noack mode. If the QStartNoAckMode packet configuration is set to AUTO, *************** Some events may be lost, rendering furth *** 3392,3397 **** --- 3399,3434 ---- return serial_open (name); } + /* Inform the target of our permission settings. The permission flags + work without this, but if the target knows the settings, it can do + a couple things. First, it can add its own check, to catch cases + that somehow manage to get by the permissions checks in target + methods. Second, if the target is wired to disallow particular + settings (for instance, a system in the field that is not set up to + be able to stop at a breakpoint), it can object to any unavailable + permissions. */ + + void + remote_set_permissions (void) + { + struct remote_state *rs = get_remote_state (); + + sprintf (rs->buf, "QAllow:" + "WriteReg:%x;WriteMem:%x;" + "InsertBreak:%x;InsertTrace:%x;" + "InsertFastTrace:%x;Stop:%x", + may_write_registers, may_write_memory, + may_insert_breakpoints, may_insert_tracepoints, + may_insert_fast_tracepoints, may_stop); + putpkt (rs->buf); + getpkt (&rs->buf, &rs->buf_size, 0); + + /* If the target didn't like the packet, warn the user. Do not try + to undo the user's settings, that would just be maddening. */ + if (strcmp (rs->buf, "OK") != 0) + warning ("Remote refused setting permissions with: %s", rs->buf); + } + /* This type describes each known response to the qSupported packet. */ struct protocol_feature *************** static struct protocol_feature remote_pr *** 3563,3568 **** --- 3600,3607 ---- PACKET_bs }, { "TracepointSource", PACKET_DISABLE, remote_supported_packet, PACKET_TracepointSource }, + { "QAllow", PACKET_DISABLE, remote_supported_packet, + PACKET_QAllow }, }; static char *remote_support_xml; *************** Specify the serial device it is connecte *** 10060,10065 **** --- 10099,10105 ---- remote_ops.to_core_of_thread = remote_core_of_thread; remote_ops.to_verify_memory = remote_verify_memory; remote_ops.to_get_tib_address = remote_get_tib_address; + remote_ops.to_set_permissions = remote_set_permissions; } /* Set up the extended remote vector by making a copy of the standard *************** Show the maximum size of the address (in *** 10535,10540 **** --- 10575,10583 ---- add_packet_config_cmd (&remote_protocol_packets[PACKET_TracepointSource], "TracepointSource", "TracepointSource", 0); + add_packet_config_cmd (&remote_protocol_packets[PACKET_QAllow], + "QAllow", "allow", 0); + /* Keep the old ``set remote Z-packet ...'' working. Each individual Z sub-packet has its own set and show commands, but users may have sets to this variable in their .gdbinit files (or in their Index: target.c =================================================================== RCS file: /cvs/src/src/gdb/target.c,v retrieving revision 1.255 diff -p -r1.255 target.c *** target.c 23 May 2010 14:23:31 -0000 1.255 --- target.c 3 Jun 2010 23:44:49 -0000 *************** static int trust_readonly = 0; *** 195,200 **** --- 195,216 ---- static int show_memory_breakpoints = 0; + /* These globals control whether GDB attempts to perform these + operations; they are useful for targets that need to prevent + inadvertant disruption, such as in non-stop mode. */ + + int may_write_registers = 1; + + int may_write_memory = 1; + + int may_insert_breakpoints = 1; + + int may_insert_tracepoints = 1; + + int may_insert_fast_tracepoints = 1; + + int may_stop = 1; + /* Non-zero if we want to see trace of target level stuff. */ static int targetdebug = 0; *************** update_current_target (void) *** 662,667 **** --- 678,684 ---- INHERIT (to_set_disconnected_tracing, t); INHERIT (to_set_circular_trace_buffer, t); INHERIT (to_get_tib_address, t); + INHERIT (to_set_permissions, t); INHERIT (to_magic, t); /* Do not inherit to_memory_map. */ /* Do not inherit to_flash_erase. */ *************** update_current_target (void) *** 858,863 **** --- 875,883 ---- de_fault (to_get_tib_address, (int (*) (ptid_t, CORE_ADDR *)) tcomplain); + de_fault (to_set_permissions, + (void (*) (void)) + target_ignore); #undef de_fault /* Finally, position the target-stack beneath the squashed *************** target_xfer_partial (struct target_ops * *** 1404,1409 **** --- 1424,1433 ---- gdb_assert (ops->to_xfer_partial != NULL); + if (writebuf && !may_write_memory) + error (_("Writing to memory is not allowed (addr %s, len %s)"), + core_addr_to_string_nz (offset), plongest (len)); + /* If this is a memory transfer, let the memory-specific code have a look at it instead. Memory transfers are more complicated. */ *************** get_target_memory_unsigned (struct targe *** 1967,1972 **** --- 1991,2026 ---- return extract_unsigned_integer (buf, len, byte_order); } + int + target_insert_breakpoint (struct gdbarch *gdbarch, + struct bp_target_info *bp_tgt) + { + if (!may_insert_breakpoints) + { + warning (_("May not insert breakpoints")); + return 1; + } + + return (*current_target.to_insert_breakpoint) (gdbarch, bp_tgt); + } + + int + target_remove_breakpoint (struct gdbarch *gdbarch, + struct bp_target_info *bp_tgt) + { + /* This is kind of a weird case to handle, but the permission might + have been changed after breakpoints were inserted - in which case + we should just take the user literally and assume that any + breakpoints should be left in place. */ + if (!may_insert_breakpoints) + { + warning (_("May not remove breakpoints")); + return 1; + } + + return (*current_target.to_remove_breakpoint) (gdbarch, bp_tgt); + } + static void target_info (char *args, int from_tty) { *************** target_find_new_threads (void) *** 2949,2954 **** --- 3003,3020 ---- } } + void + target_stop (ptid_t ptid) + { + if (!may_stop) + { + warning (_("May not interrupt or stop the target, ignoring attempt")); + return; + } + + (*current_target.to_stop) (ptid); + } + static void debug_to_post_attach (int pid) { *************** target_store_registers (struct regcache *** 3058,3063 **** --- 3124,3132 ---- { struct target_ops *t; + if (!may_write_registers) + error (_("Writing to registers is not allowed (regno %d)"), regno); + for (t = current_target.beneath; t != NULL; t = t->beneath) { if (t->to_store_registers != NULL) *************** show_maintenance_target_async_permitted *** 3675,3680 **** --- 3744,3805 ---- Controlling the inferior in asynchronous mode is %s.\n"), value); } + /* Temporary copies of permission settings. */ + + static int may_write_registers_1 = 1; + static int may_write_memory_1 = 1; + static int may_insert_breakpoints_1 = 1; + static int may_insert_tracepoints_1 = 1; + static int may_insert_fast_tracepoints_1 = 1; + static int may_stop_1 = 1; + + /* Make the user-set values match the real values again. */ + + void + update_target_permissions (void) + { + may_write_registers_1 = may_write_registers; + may_write_memory_1 = may_write_memory; + may_insert_breakpoints_1 = may_insert_breakpoints; + may_insert_tracepoints_1 = may_insert_tracepoints; + may_insert_fast_tracepoints_1 = may_insert_fast_tracepoints; + may_stop_1 = may_stop; + } + + /* The one function handles (most of) the permission flags in the same + way. */ + + static void + set_target_permissions (char *args, int from_tty, + struct cmd_list_element *c) + { + if (target_has_execution) + { + update_target_permissions (); + error (_("Cannot change this setting while the inferior is running.")); + } + + /* Make the real values match the user-changed values. */ + may_write_registers = may_write_registers_1; + may_insert_breakpoints = may_insert_breakpoints_1; + may_insert_tracepoints = may_insert_tracepoints_1; + may_insert_fast_tracepoints = may_insert_fast_tracepoints_1; + may_stop = may_stop_1; + update_observer_mode (); + } + + /* Set memory write permission independently of observer mode. */ + + static void + set_write_memory_permission (char *args, int from_tty, + struct cmd_list_element *c) + { + /* Make the real values match the user-changed values. */ + may_write_memory = may_write_memory_1; + update_observer_mode (); + } + + void initialize_targets (void) { *************** By default, caching for stack access is *** 3733,3737 **** --- 3858,3917 ---- show_stack_cache_enabled_p, &setlist, &showlist); + add_setshow_boolean_cmd ("may-write-registers", class_support, + &may_write_registers_1, _("\ + Set permission to write into registers."), _("\ + Show permission to write into registers."), _("\ + When this permission is on, GDB may write into the target's registers.\n\ + Otherwise, any sort of write attempt will result in an error."), + set_target_permissions, NULL, + &setlist, &showlist); + + add_setshow_boolean_cmd ("may-write-memory", class_support, + &may_write_memory_1, _("\ + Set permission to write into target memory."), _("\ + Show permission to write into target memory."), _("\ + When this permission is on, GDB may write into the target's memory.\n\ + Otherwise, any sort of write attempt will result in an error."), + set_write_memory_permission, NULL, + &setlist, &showlist); + + add_setshow_boolean_cmd ("may-insert-breakpoints", class_support, + &may_insert_breakpoints_1, _("\ + Set permission to insert breakpoints in the target."), _("\ + Show permission to insert breakpoints in the target."), _("\ + When this permission is on, GDB may insert breakpoints in the program.\n\ + Otherwise, any sort of insertion attempt will result in an error."), + set_target_permissions, NULL, + &setlist, &showlist); + + add_setshow_boolean_cmd ("may-insert-tracepoints", class_support, + &may_insert_tracepoints_1, _("\ + Set permission to insert tracepoints in the target."), _("\ + Show permission to insert tracepoints in the target."), _("\ + When this permission is on, GDB may insert tracepoints in the program.\n\ + Otherwise, any sort of insertion attempt will result in an error."), + set_target_permissions, NULL, + &setlist, &showlist); + + add_setshow_boolean_cmd ("may-insert-fast-tracepoints", class_support, + &may_insert_fast_tracepoints_1, _("\ + Set permission to insert fast tracepoints in the target."), _("\ + Show permission to insert fast tracepoints in the target."), _("\ + When this permission is on, GDB may insert fast tracepoints.\n\ + Otherwise, any sort of insertion attempt will result in an error."), + set_target_permissions, NULL, + &setlist, &showlist); + + add_setshow_boolean_cmd ("may-interrupt", class_support, + &may_stop_1, _("\ + Set permission to interrupt or signal the target."), _("\ + Show permission to interrupt or signal the target."), _("\ + When this permission is on, GDB may interrupt/stop the target's execution.\n\ + Otherwise, any attempt to interrupt or stop will be ignored."), + set_target_permissions, NULL, + &setlist, &showlist); + + target_dcache = dcache_init (); } Index: target.h =================================================================== RCS file: /cvs/src/src/gdb/target.h,v retrieving revision 1.182 diff -p -r1.182 target.h *** target.h 23 May 2010 14:23:31 -0000 1.182 --- target.h 3 Jun 2010 23:44:49 -0000 *************** struct target_ops *** 686,691 **** --- 686,694 ---- a Windows OS specific feature. */ int (*to_get_tib_address) (ptid_t ptid, CORE_ADDR *addr); + /* Send the new settings of write permission variables. */ + void (*to_set_permissions) (void); + int to_magic; /* Need sub-structure for target machine related rather than comm related? */ *************** extern int inferior_has_called_syscall ( *** 889,902 **** /* Insert a breakpoint at address BP_TGT->placed_address in the target machine. Result is 0 for success, or an errno value. */ ! #define target_insert_breakpoint(gdbarch, bp_tgt) \ ! (*current_target.to_insert_breakpoint) (gdbarch, bp_tgt) /* Remove a breakpoint at address BP_TGT->placed_address in the target machine. Result is 0 for success, or an errno value. */ ! #define target_remove_breakpoint(gdbarch, bp_tgt) \ ! (*current_target.to_remove_breakpoint) (gdbarch, bp_tgt) /* Initialize the terminal settings we record for the inferior, before we actually run the inferior. */ --- 892,905 ---- /* Insert a breakpoint at address BP_TGT->placed_address in the target machine. Result is 0 for success, or an errno value. */ ! extern int target_insert_breakpoint (struct gdbarch *gdbarch, ! struct bp_target_info *bp_tgt); /* Remove a breakpoint at address BP_TGT->placed_address in the target machine. Result is 0 for success, or an errno value. */ ! extern int target_remove_breakpoint (struct gdbarch *gdbarch, ! struct bp_target_info *bp_tgt); /* Initialize the terminal settings we record for the inferior, before we actually run the inferior. */ *************** extern void target_find_new_threads (voi *** 1091,1097 **** Unix, this should act like SIGSTOP). This function is normally used by GUIs to implement a stop button. */ ! #define target_stop(ptid) (*current_target.to_stop) (ptid) /* Send the specified COMMAND to the target's monitor (shell,interpreter) for execution. The result of the query is --- 1094,1100 ---- Unix, this should act like SIGSTOP). This function is normally used by GUIs to implement a stop button. */ ! extern void target_stop (ptid_t ptid); /* Send the specified COMMAND to the target's monitor (shell,interpreter) for execution. The result of the query is *************** extern int target_search_memory (CORE_AD *** 1378,1383 **** --- 1381,1389 ---- #define target_get_tib_address(ptid, addr) \ (*current_target.to_get_tib_address) ((ptid), (addr)) + #define target_set_permissions() \ + (*current_target.to_set_permissions) () + /* Command logging facility. */ #define target_log_command(p) \ *************** extern enum target_signal target_signal_ *** 1540,1545 **** --- 1546,1560 ---- to restore it back to the current value. */ extern struct cleanup *make_show_memory_breakpoints_cleanup (int show); + extern int may_write_registers; + extern int may_write_memory; + extern int may_insert_breakpoints; + extern int may_insert_tracepoints; + extern int may_insert_fast_tracepoints; + extern int may_stop; + + extern void update_target_permissions (void); + /* Imported from machine dependent code */ Index: tracepoint.c =================================================================== RCS file: /cvs/src/src/gdb/tracepoint.c,v retrieving revision 1.188 diff -p -r1.188 tracepoint.c *** tracepoint.c 27 May 2010 22:06:00 -0000 1.188 --- tracepoint.c 3 Jun 2010 23:44:49 -0000 *************** start_tracing (void) *** 1490,1496 **** int ix; struct breakpoint *t; struct trace_state_variable *tsv; ! int any_enabled = 0; tp_vec = all_tracepoints (); --- 1490,1496 ---- int ix; struct breakpoint *t; struct trace_state_variable *tsv; ! int any_enabled = 0, num_to_download = 0; tp_vec = all_tracepoints (); *************** start_tracing (void) *** 1504,1513 **** for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++) { if (t->enable_state == bp_enabled) ! { ! any_enabled = 1; ! break; ! } } /* No point in tracing with only disabled tracepoints. */ --- 1504,1518 ---- for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++) { if (t->enable_state == bp_enabled) ! any_enabled = 1; ! ! if ((t->type == bp_fast_tracepoint ! ? may_insert_fast_tracepoints ! : may_insert_tracepoints)) ! ++num_to_download; ! else ! warning (_("May not insert %stracepoints, skipping tracepoint %d"), ! (t->type == bp_fast_tracepoint ? "fast " : ""), t->number); } /* No point in tracing with only disabled tracepoints. */ *************** start_tracing (void) *** 1517,1526 **** --- 1522,1542 ---- error (_("No tracepoints enabled, not starting trace")); } + if (num_to_download <= 0) + { + VEC_free (breakpoint_p, tp_vec); + error (_("No tracepoints that may be downloaded, not starting trace")); + } + target_trace_init (); for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++) { + if ((t->type == bp_fast_tracepoint + ? !may_insert_fast_tracepoints + : !may_insert_tracepoints)) + continue; + t->number_on_target = 0; target_download_tracepoint (t); t->number_on_target = t->number; Index: doc/gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.720 diff -p -r1.720 gdb.texinfo *** doc/gdb.texinfo 2 Jun 2010 19:37:56 -0000 1.720 --- doc/gdb.texinfo 3 Jun 2010 23:44:49 -0000 *************** you examine the stopped thread in the de *** 4958,4963 **** --- 4958,4964 ---- * Background Execution:: Running your program asynchronously * Thread-Specific Breakpoints:: Controlling breakpoints * Interrupted System Calls:: GDB may interfere with system calls + * Observer Mode:: GDB does not alter program behavior @end menu @node All-Stop Mode *************** monitor certain events such as thread cr *** 5318,5323 **** --- 5319,5421 ---- When such an event happens, a system call in another thread may return prematurely, even though your program does not appear to stop. + @node Observer Mode + @subsection Observer Mode + + If you want to build on non-stop mode and observe program behavior + without any chance of disruption by @value{GDBN}, you can set + variables to disable all of the debugger's attempts to modify state, + whether by writing memory, inserting breakpoints, etc. These operate + at a low level, intercepting operations from all commands. + + When all of these are set to @code{off}, then @value{GDBN} is said to + be @dfn{observer mode}. As a convenience, the variable + @code{observer} can be set to disable these, plus enable non-stop + mode. + + Note that @value{GDBN} will not prevent you from making nonsensical + combinations of these settings. For instance, if you have enabled + @code{may-insert-breakpoints} but disabled @code{may-write-memory}, + then breakpoints that work by writing trap instructions into the code + stream will still not be able to be placed. + + @table @code + + @kindex observer + @item set observer on + @itemx set observer off + When set to @code{on}, this disables all the permission variables + below (except for @code{insert-fast-tracepoints}), plus enables + non-stop debugging. Setting this to @code{off} switches back to + normal debugging, though remaining in non-stop mode. + + @item show observer + Show whether observer mode is on or off. + + @kindex may-write-registers + @item set may-write-registers on + @itemx set may-write-registers off + This controls whether @value{GDBN} will attempt to alter the values of + registers, such as with assignment expressions in @code{print}, or the + @code{jump} command. It defaults to @code{on}. + + @item show may-write-registers + Show the current permission to write registers. + + @kindex may-write-memory + @item set may-write-memory on + @itemx set may-write-memory off + This controls whether @value{GDBN} will attempt to alter the contents + of memory, such as with assignment expressions in @code{print}. It + defaults to @code{on}. + + @item show may-write-memory + Show the current permission to write memory. + + @kindex may-insert-breakpoints + @item set may-insert-breakpoints on + @itemx set may-insert-breakpoints off + This controls whether @value{GDBN} will attempt to insert breakpoints. + This affects all breakpoints, including internal breakpoints defined + by @value{GDBN}. It defaults to @code{on}. + + @item show may-insert-breakpoints + Show the current permission to insert breakpoints. + + @kindex may-insert-tracepoints + @item set may-insert-tracepoints on + @itemx set may-insert-tracepoints off + This controls whether @value{GDBN} will attempt to insert (regular) + tracepoints at the beginning of a tracing experiment. It affects only + non-fast tracepoints, fast tracepoints being under the control of + @code{may-insert-fast-tracepoints}. It defaults to @code{on}. + + @item show may-insert-tracepoints + Show the current permission to insert tracepoints. + + @kindex may-insert-fast-tracepoints + @item set may-insert-fast-tracepoints on + @itemx set may-insert-fast-tracepoints off + This controls whether @value{GDBN} will attempt to insert fast + tracepoints at the beginning of a tracing experiment. It affects only + fast tracepoints, regular (non-fast) tracepoints being under the + control of @code{may-insert-tracepoints}. It defaults to @code{on}. + + @item show may-insert-fast-tracepoints + Show the current permission to insert fast tracepoints. + + @kindex may-interrupt + @item set may-interrupt on + @itemx set may-interrupt off + This controls whether @value{GDBN} will attempt to interrupt or stop + program execution. When this variable is @code{off}, the + @code{interrupt} command will have no effect, nor will + @kbd{Ctrl-c}. It defaults to @code{on}. + + @item show may-interrupt + Show the current permission to interrupt or stop the program. + + @end table @node Reverse Execution @chapter Running programs backward *************** Here are the currently defined query and *** 31168,31173 **** --- 31266,31283 ---- @table @samp + @item QAllow:@var{op}:@var{val}@dots{} + @cindex @samp{QAllow} packet + Specify which operations @value{GDBN} expects to request of the + target, as a semicolon-separated list of operation name and value + pairs. Possible values for @var{op} include @samp{WriteReg}, + @samp{WriteMem}, @samp{InsertBreak}, @samp{InsertTrace}, + @samp{InsertFastTrace}, and @samp{Stop}. @var{val} is either 0, + indicating that @value{GDBN} will not request the operation, or 1, + indicating that it may. (The target can then use this to set up its + own internals optimally, for instance if the debugger never expects to + insert breakpoints, it may not need to install its own trap handler.) + @item qC @cindex current thread, remote request @cindex @samp{qC} packet *************** These are the currently defined stub fea *** 31689,31694 **** --- 31799,31809 ---- @tab @samp{-} @tab No + @item @samp{QAllow} + @tab No + @tab @samp{-} + @tab No + @end multitable These are the currently defined stub features, in more detail: *************** The remote stub accepts and implements t *** 31786,31791 **** --- 31901,31909 ---- The remote stub understands the @samp{QTDPsrc} packet that supplies the source form of tracepoint definitions. + @item QAllow + The remote stub understands the @samp{QAllow} packet. + @end table @item qSymbol:: Index: testsuite/gdb.base/permissions.exp =================================================================== RCS file: testsuite/gdb.base/permissions.exp diff -N testsuite/gdb.base/permissions.exp *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/gdb.base/permissions.exp 3 Jun 2010 23:44:49 -0000 *************** *** 0 **** --- 1,101 ---- + # Copyright 2010 Free Software Foundation, Inc. + + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 3 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program. If not, see . + + # Tests for permissions and observer mode. + + # The permissions flags are only fully functional with stubs or targets + # that can run asynchronously. + + set testfile permission + set srcfile start.c + set binfile ${objdir}/${subdir}/${testfile} + + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug nowarnings}] != "" } { + untested permissions.exp + return -1 + } + + if [get_compiler_info $binfile] { + return -1 + } + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + + gdb_test "show may-write-registers" \ + "Permission to write into registers is on." + + gdb_test "show may-write-memory" \ + "Permission to write into target memory is on." + + gdb_test "show may-insert-breakpoints" \ + "Permission to insert breakpoints in the target is on." + + gdb_test "show may-insert-tracepoints" \ + "Permission to insert tracepoints in the target is on." + + gdb_test "show may-insert-fast-tracepoints" \ + "Permission to insert fast tracepoints in the target is on." + + gdb_test "show may-interrupt" \ + "Permission to interrupt or signal the target is on." + + gdb_test "set observer on" "Observer mode is now on." "enable observer mode" + + gdb_test "show may-write-memory" \ + "Permission to write into target memory is off." + + gdb_test "show may-write-registers" \ + "Permission to write into registers is off." + + gdb_test "show may-insert-breakpoints" \ + "Permission to insert breakpoints in the target is off." + + gdb_test "show may-insert-tracepoints" \ + "Permission to insert tracepoints in the target is off." + + gdb_test "show may-insert-fast-tracepoints" \ + "Permission to insert fast tracepoints in the target is on." + + gdb_test "show may-interrupt" \ + "Permission to interrupt or signal the target is off." + + gdb_test "set observer off" "Observer mode is now off." "disable observer mode" + + # Go back to all-stop mode. + + gdb_test_no_output "set non-stop off" + + gdb_load ${binfile} + + if ![runto_main] then { + perror "couldn't run to breakpoint" + continue + } + + gdb_test "print x = 45" "$decimal = 45" "set a global" + + gdb_test "print x" "$decimal = 45" + + gdb_test "set may-write-memory off" + + gdb_test "print x = 92" "Writing to memory is not allowed.*" \ + "try to set a global" + + gdb_test "print x" "$decimal = 45" + + # FIXME Add tests for other flags when a testsuite-able target becomes + # available.