From 999dd04b89b61e097f58c43dbc68e0922917302e Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Wed, 13 Apr 1994 21:57:00 +0000 Subject: * breakpoint.h (enum bptype): Add bp_hardware_watchpoint and bp_watchpoint_scope breakpoints. (struct breakpoint): Add val_chain and related_breakpoint fields for use by watchpoints. * breakpoint.c (within_scope): Delete. No longer used. (TARGET_CAN_USE_HARDWARE_WATCHPOINT): Provide default definition. (target_{remove,insert}_watchpoint): Likewise. (can_use_hardware_watchpoint): New function. (remove_breakpoint): New function to remove a single breakpoint or hardware watchpoint. (insert_breakpoints): Handle insertion of hardware watchpoints. Store a copy of the value chain derived from the watchpoint expression. (remove_breakpoints): Simplify by using remove_breakpoint. (delete_breakpoint): Likewise. (watchpoint_check): Delete the watchpoint and watchpoint scope breakpoints when the watchpoint goes out of scope. Save & restore the current frame after checking watchpoints. (breakpoint_init_inferior): Likewise (restarting the program makes all local watchpoints go out of scope). (bpstat_stop_status): Handle hardware watchpoints much like normal watchpoints. Delete the watchpoint and watchpoint scope breakpoint when the watchpoint goes out of scope. Remove and reinsert all breakpoints before returning if we stopped when a hardware watchpoint fired. (watch_command): Use a hardware watchpoint when possible. If watching a local expression, build a scope breakpoint too. (map_breakpoint_numbers): Also call given function for any related breakpoints. (disable_breakpoint): Never disable a scope breakpoint. (enable_breakpoint): Handle hardware breakpoints much like normal breakpoints, but recompute the watchpoint_scope breakpoint's frame and address (if we have an associated scope breakpoint). (read_memory_nobpt): Handle hardware watchpoints like normal watchpoints. When necessary handle watchpoint_scope breakpoints. (print_it_normal, bpstat_what, breakpoint_1, mention): Likewise. (clear_command, breakpoint_re_set_one, enable_command): Likewise. (disable_command): Likewise. * blockframe.c (find_frame_addr_in_frame_chain): New function. Extern prototype added to frame.h * infrun.c (wait_for_inferior): Set current_frame and select a frame before checking if we stopped due to a hardare watchpoint firing. Handle stepping over hardware watchpoints. (normal_stop): Remove unnecessary call to select_frame. * value.h (value_release_to_mark): Declare. * values.c (value_release_to_mark): New function. * procfs.c (procfs_wait): Add cases for hardware watchpoints. (procfs_set_watchpoint, procfs_stopped_by_watchpoint): New functions. * hppab-nat.c (hppa_set_watchpoint): New function. * config/pa/nm-hppab.h (STOPPED_BY_WATCHPOINT): Define. (HAVE_STEPPABLE_WATCHPOINT): Define. (TARGET_CAN_USE_HARDWARE_WATCHPOINT): Define. (target_{insert,delete}_watchpoint): Define. --- gdb/procfs.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'gdb/procfs.c') diff --git a/gdb/procfs.c b/gdb/procfs.c index be94803..2215ce3 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -2322,6 +2322,10 @@ wait_again: case FLTBPT: case FLTTRACE: statval = (SIGTRAP << 8) | 0177; + break; + case FLTWATCH: + case FLTKWATCH: + statval = (SIGTRAP << 8) | 0177; break; case FLTSTACK: case FLTACCESS: @@ -3529,6 +3533,56 @@ procfs_can_run () return(1); } +/* Insert a watchpoint */ +int +procfs_set_watchpoint(pid, addr, len, rw) + int pid; + CORE_ADDR addr; + int len; + int rw; +{ + struct procinfo *pi; + prwatch_t wpt; + + pi = find_procinfo (pid == -1 ? inferior_pid : pid, 0); + wpt.pr_vaddr = (caddr_t)addr; + wpt.pr_size = len; + wpt.pr_wflags = ((rw & 1) ? MA_READ : 0) | ((rw & 2) ? MA_WRITE : 0); + if (ioctl (pi->fd, PIOCSWATCH, &wpt) < 0) + { + if (errno == E2BIG) + return -1; + /* Currently it sometimes happens that the same watchpoint gets + deleted twice - don't die in this case (FIXME please) */ + if (errno == ESRCH && len == 0) + return 0; + print_sys_errmsg (pi->pathname, errno); + error ("PIOCSWATCH failed"); + } + return 0; +} + +int +procfs_stopped_by_watchpoint(pid) + int pid; +{ + struct procinfo *pi; + short what; + short why; + + pi = find_procinfo (pid == -1 ? inferior_pid : pid, 0); + if (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP)) + { + why = pi->prstatus.pr_why; + what = pi->prstatus.pr_what; + if (why == PR_FAULTED + && (what == FLTWATCH) || (what == FLTKWATCH)) + return what; + } + return 0; +} + + struct target_ops procfs_ops = { "procfs", /* to_shortname */ "Unix /proc child process", /* to_longname */ -- cgit v1.1