2010-06-11 Stan Shebs <stan@codesourcery.com>

Add per-operation permission flags.

	* target.h (struct target_ops): New method to_set_permissions.
	(target_set_permissions): New macro.
	(target_insert_breakpoint): Change macro to function.
	(target_remove_breakpoint): Ditto.
	(target_stop): Ditto.
	(may_write_registers): Declare.
	(may_write_memory): Declare.
	(may_insert_breakpoints): Declare.
	(may_insert_tracepoints): Declare.
	(may_insert_fast_tracepoints): Declare.
	(may_stop): Declare.
	* target.c (may_write_registers, may_write_registers_1): New globals.
	(may_write_memory, may_write_memory_1): New globals.
	(may_insert_breakpoints, may_insert_breakpoints_1): New globals.
	(may_insert_tracepoints, may_insert_tracepoints_1): New globals.
	(may_insert_fast_tracepoints, may_insert_fast_tracepoints_1): New
	globals.
	(may_stop, may_stop_1): New global.
	(target_xfer_partial): Test for write permission.
	(target_store_registers): Ditto.
	(target_insert_breakpoint): New function.
	(target_remove_breakpoint): New function.
	(target_stop): New function.
	(_initialize_targets): Add new set/show variables.
	(set_write_memory_permission): New function.
	(update_target_permissions): New function.
	(set_target_permissions): New function.
	(update_current_target): Default to_set_permissions.
	(_initialize_targets): Use new globals and setter function.
	* tracepoint.c (start_tracing): Test for permission.
	* inferior.h (update_observer_mode): Declare.
	* infrun.c (non_stop_1): Define earlier.
	(observer_mode, observer_mode_1): New globals.
	(set_observer_mode, show_observer_mode): New functions.
	(update_observer_mode): New function.
	(_initialize_infrun): Define "set observer" command.
	* remote.c (PACKET_QAllow): New optional packet.
	(remote_protocol_features): Add QAllow.
	(remote_set_permissions): New function.
	(remote_start_remote): Call it.
	(init_remote_ops): Add it to target vector.
	(_initialize_remote): Add config command for QAllow.

	* gdb.texinfo (Observer Mode): New section.
	(General Query Packets): Document QAllow.

	* gdb.base/permissions.exp: New file.
This commit is contained in:
Stan Shebs 2010-06-12 00:05:22 +00:00
parent 139f2ac873
commit d914c394a9
11 changed files with 634 additions and 12 deletions

View file

@ -1,3 +1,50 @@
2010-06-11 Stan Shebs <stan@codesourcery.com>
Add per-operation permission flags.
* target.h (struct target_ops): New method to_set_permissions.
(target_set_permissions): New macro.
(target_insert_breakpoint): Change macro to function.
(target_remove_breakpoint): Ditto.
(target_stop): Ditto.
(may_write_registers): Declare.
(may_write_memory): Declare.
(may_insert_breakpoints): Declare.
(may_insert_tracepoints): Declare.
(may_insert_fast_tracepoints): Declare.
(may_stop): Declare.
* target.c (may_write_registers, may_write_registers_1): New globals.
(may_write_memory, may_write_memory_1): New globals.
(may_insert_breakpoints, may_insert_breakpoints_1): New globals.
(may_insert_tracepoints, may_insert_tracepoints_1): New globals.
(may_insert_fast_tracepoints, may_insert_fast_tracepoints_1): New
globals.
(may_stop, may_stop_1): New global.
(target_xfer_partial): Test for write permission.
(target_store_registers): Ditto.
(target_insert_breakpoint): New function.
(target_remove_breakpoint): New function.
(target_stop): New function.
(_initialize_targets): Add new set/show variables.
(set_write_memory_permission): New function.
(update_target_permissions): New function.
(set_target_permissions): New function.
(update_current_target): Default to_set_permissions.
(_initialize_targets): Use new globals and setter function.
* tracepoint.c (start_tracing): Test for permission.
* inferior.h (update_observer_mode): Declare.
* infrun.c (non_stop_1): Define earlier.
(observer_mode, observer_mode_1): New globals.
(set_observer_mode, show_observer_mode): New functions.
(update_observer_mode): New function.
(_initialize_infrun): Define "set observer" command.
* remote.c (PACKET_QAllow): New optional packet.
(remote_protocol_features): Add QAllow.
(remote_set_permissions): New function.
(remote_start_remote): Call it.
(init_remote_ops): Add it to target vector.
(_initialize_remote): Add config command for QAllow.
2010-06-11 Tom Tromey <tromey@redhat.com>
* dwarf2read.c (dwarf2_add_member_fn): Handle correct form of

View file

@ -1,3 +1,8 @@
2010-06-11 Stan Shebs <stan@codesourcery.com>
* gdb.texinfo (Observer Mode): New section.
(General Query Packets): Document QAllow.
2010-06-04 Doug Evans <dje@google.com>
* gdb.texinfo (Python API): New node `Disabling Pretty-Printers'.

View file

@ -4958,6 +4958,7 @@ you examine the stopped thread in the debugger.
* 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
@ -5318,6 +5319,103 @@ monitor certain events such as thread creation and thread destruction.
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
@ -31190,6 +31288,18 @@ Here are the currently defined query and set packets:
@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
@ -31711,6 +31821,11 @@ These are the currently defined stub features and their properties:
@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:
@ -31808,6 +31923,9 @@ The remote stub accepts and implements the reverse step packet
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::

View file

@ -628,4 +628,6 @@ extern int number_of_inferiors (void);
extern struct inferior *add_inferior_with_spaces (void);
extern void update_observer_mode (void);
#endif /* !defined (INFERIOR_H) */

View file

@ -178,6 +178,85 @@ show_debug_infrun (struct ui_file *file, int from_tty,
#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. */
@ -6423,7 +6502,6 @@ show_exec_direction_func (struct ui_file *out, int from_tty,
/* 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,
@ -6725,4 +6803,17 @@ Tells gdb whether to detach the child of a fork."),
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);
}

View file

@ -212,6 +212,8 @@ static void show_remote_protocol_packet_cmd (struct ui_file *file,
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);
@ -1213,6 +1215,7 @@ enum {
PACKET_bc,
PACKET_bs,
PACKET_TracepointSource,
PACKET_QAllow,
PACKET_MAX
};
@ -3047,6 +3050,10 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
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,
@ -3393,6 +3400,36 @@ Some events may be lost, rendering further debugging impossible."));
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
@ -3564,6 +3601,8 @@ static struct protocol_feature remote_protocol_features[] = {
PACKET_bs },
{ "TracepointSource", PACKET_DISABLE, remote_supported_packet,
PACKET_TracepointSource },
{ "QAllow", PACKET_DISABLE, remote_supported_packet,
PACKET_QAllow },
};
static char *remote_support_xml;
@ -10061,6 +10100,7 @@ Specify the serial device it is connected to\n\
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
@ -10536,6 +10576,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
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

View file

@ -195,6 +195,22 @@ static int trust_readonly = 0;
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;
@ -662,6 +678,7 @@ update_current_target (void)
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. */
@ -858,6 +875,9 @@ update_current_target (void)
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
@ -1404,6 +1424,10 @@ target_xfer_partial (struct target_ops *ops,
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. */
@ -1967,6 +1991,36 @@ get_target_memory_unsigned (struct target_ops *ops, CORE_ADDR addr,
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)
{
@ -2949,6 +3003,18 @@ target_find_new_threads (void)
}
}
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)
{
@ -3058,6 +3124,9 @@ target_store_registers (struct regcache *regcache, int regno)
{
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)
@ -3675,6 +3744,62 @@ show_maintenance_target_async_permitted (struct ui_file *file, int from_tty,
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)
{
@ -3733,5 +3858,60 @@ By default, caching for stack access is on."),
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 ();
}

View file

@ -686,6 +686,9 @@ struct target_ops
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?
*/
@ -889,14 +892,14 @@ extern int inferior_has_called_syscall (ptid_t pid, int *syscall_number);
/* 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)
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. */
#define target_remove_breakpoint(gdbarch, bp_tgt) \
(*current_target.to_remove_breakpoint) (gdbarch, bp_tgt)
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. */
@ -1091,7 +1094,7 @@ extern void target_find_new_threads (void);
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)
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
@ -1378,6 +1381,9 @@ extern int target_search_memory (CORE_ADDR start_addr,
#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) \
@ -1540,6 +1546,15 @@ extern enum target_signal target_signal_from_command (int);
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 */

View file

@ -1,4 +1,8 @@
:010-06-11 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
2010-06-11 Stan Shebs <stan@codesourcery.com>
* gdb.base/permissions.exp: New file.
2010-06-11 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* gdb.base/valgrind-db-attach.exp: Fail gracefully if valgrind
does not support ELF executable class.

View file

@ -0,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 <http://www.gnu.org/licenses/>.
# 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.

View file

@ -1490,7 +1490,7 @@ start_tracing (void)
int ix;
struct breakpoint *t;
struct trace_state_variable *tsv;
int any_enabled = 0;
int any_enabled = 0, num_to_download = 0;
tp_vec = all_tracepoints ();
@ -1504,10 +1504,15 @@ start_tracing (void)
for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
{
if (t->enable_state == bp_enabled)
{
any_enabled = 1;
break;
}
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. */
@ -1517,10 +1522,21 @@ start_tracing (void)
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;