Index: breakpoint.c =================================================================== RCS file: /cvs/src/src/gdb/breakpoint.c,v retrieving revision 1.174 diff -u -p -r1.174 breakpoint.c --- breakpoint.c 7 Jun 2004 17:58:32 -0000 1.174 +++ breakpoint.c 11 Jun 2004 21:22:42 -0000 @@ -2120,8 +2120,13 @@ print_it_typical (bpstat bs) break; case bp_thread_event: - /* Not sure how we will get here. - GDB should not stop for these breakpoints. */ + /* We can only get here legitimately if something further on the bs + list has caused the stop status to be noisy. A valid example + of this is a new thread event and a software watchpoint have + both occurred. */ + if (bs->next) + return PRINT_UNKNOWN; + printf_filtered ("Thread Event Breakpoint: gdb should not stop!\n"); return PRINT_NOTHING; break; @@ -2683,45 +2688,100 @@ bpstat_stop_status (CORE_ADDR bp_addr, p if (b->type == bp_watchpoint || b->type == bp_hardware_watchpoint) { - char *message = xstrprintf ("Error evaluating expression for watchpoint %d\n", + CORE_ADDR addr; + struct value *v; + int found = 0; + + /* If we have a hardware watchpoint, ensure that the address + being watched caused the trap event. */ + if (b->type == bp_hardware_watchpoint) + { + addr = target_stopped_data_address (); + if (addr == 0) + { + /* Don't stop. */ + bs->print_it = print_it_noop; + bs->stop = 0; + continue; + } + for (v = b->val_chain; v; v = v->next) + { + if (VALUE_LVAL (v) == lval_memory + && ! VALUE_LAZY (v)) + { + struct type *vtype = check_typedef (VALUE_TYPE (v)); + + if (v == b->val_chain + || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT + && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) + { + CORE_ADDR vaddr; + + vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); + /* Exact match not required. Within range is + sufficient. */ + if (addr >= vaddr && + addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v))) + found = 1; + } + } + } + } + else /* For a non-hardware watchpoint we need to test values. */ + found = 1; + + if (found) + { + char *message = xstrprintf ("Error evaluating expression for watchpoint %d\n", b->number); - struct cleanup *cleanups = make_cleanup (xfree, message); - int e = catch_errors (watchpoint_check, bs, message, - RETURN_MASK_ALL); - do_cleanups (cleanups); - switch (e) + struct cleanup *cleanups = make_cleanup (xfree, message); + int e = catch_errors (watchpoint_check, bs, message, + RETURN_MASK_ALL); + do_cleanups (cleanups); + switch (e) + { + case WP_DELETED: + /* We've already printed what needs to be printed. */ + /* Actually this is superfluous, because by the time we + call print_it_typical() the wp will be already deleted, + and the function will return immediately. */ + bs->print_it = print_it_done; + /* Stop. */ + break; + case WP_VALUE_CHANGED: + /* Stop. */ + ++(b->hit_count); + break; + case WP_VALUE_NOT_CHANGED: + /* Don't stop. */ + bs->print_it = print_it_noop; + bs->stop = 0; + continue; + default: + /* Can't happen. */ + /* FALLTHROUGH */ + case 0: + /* Error from catch_errors. */ + printf_filtered ("Watchpoint %d deleted.\n", b->number); + if (b->related_breakpoint) + b->related_breakpoint->disposition = disp_del_at_next_stop; + b->disposition = disp_del_at_next_stop; + /* We've already printed what needs to be printed. */ + bs->print_it = print_it_done; + + /* Stop. */ + break; + } + } + else /* found == 0 */ { - case WP_DELETED: - /* We've already printed what needs to be printed. */ - /* Actually this is superfluous, because by the time we - call print_it_typical() the wp will be already deleted, - and the function will return immediately. */ - bs->print_it = print_it_done; - /* Stop. */ - break; - case WP_VALUE_CHANGED: - /* Stop. */ - ++(b->hit_count); - break; - case WP_VALUE_NOT_CHANGED: - /* Don't stop. */ + /* This is a case where some watchpoint(s) triggered, + but not at the address of this watchpoint (FOUND + was left zero). So don't print anything for this + watchpoint. */ bs->print_it = print_it_noop; bs->stop = 0; - continue; - default: - /* Can't happen. */ - /* FALLTHROUGH */ - case 0: - /* Error from catch_errors. */ - printf_filtered ("Watchpoint %d deleted.\n", b->number); - if (b->related_breakpoint) - b->related_breakpoint->disposition = disp_del_at_next_stop; - b->disposition = disp_del_at_next_stop; - /* We've already printed what needs to be printed. */ - bs->print_it = print_it_done; - - /* Stop. */ - break; + continue; } } else if (b->type == bp_read_watchpoint || @@ -2733,7 +2793,12 @@ bpstat_stop_status (CORE_ADDR bp_addr, p addr = target_stopped_data_address (); if (addr == 0) - continue; + { + /* Don't stop. */ + bs->print_it = print_it_noop; + bs->stop = 0; + continue; + } for (v = b->val_chain; v; v = v->next) { if (VALUE_LVAL (v) == lval_memory