2015-06-17 Luis Machado * breakpoint.c (make_breakpoint_permanent): Remove unused function. (add_location_to_breakpoint): Don't mark permanent locations as inserted. Update and expand comment about permanent locations. (bp_loc_is_permanent): Don't return 0 for bp_call_dummy. Move comment to add_location_to_breakpoint. (update_global_location_list): Don't error out if a permanent breakpoint is not marked inserted. Don't error out if a non-permanent breakpoint location is inserted on top of a permanent breakpoint. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 657c58e..d731f1f 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -7431,26 +7431,6 @@ set_raw_breakpoint (struct gdbarch *gdbarch, return b; } - -/* Note that the breakpoint object B describes a permanent breakpoint - instruction, hard-wired into the inferior's code. */ -void -make_breakpoint_permanent (struct breakpoint *b) -{ - struct bp_location *bl; - - /* By definition, permanent breakpoints are already present in the - code. Mark all locations as inserted. For now, - make_breakpoint_permanent is called in just one place, so it's - hard to say if it's reasonable to have permanent breakpoint with - multiple locations or not, but it's easy to implement. */ - for (bl = b->loc; bl; bl = bl->next) - { - bl->permanent = 1; - bl->inserted = 1; - } -} - /* Call this routine when stepping and nexting to enable a breakpoint if we do a longjmp() or 'throw' in TP. FRAME is the frame which initiated the operation. */ @@ -8918,11 +8898,21 @@ add_location_to_breakpoint (struct breakpoint *b, set_breakpoint_location_function (loc, sal->explicit_pc || sal->explicit_line); + /* While by definition, permanent breakpoints are already present in the + code, we don't mark the location as inserted. Normally one would expect + that GDB could rely on that breakpoint instruction to stop the program, + thus removing the need to insert its own breakpoint, except that executing + the breakpoint instruction can kill the target instead of reporting a + SIGTRAP. E.g., on SPARC, when interrupts are disabled, executing the + instruction resets the CPU, so QEMU 2.0.0 for SPARC correspondingly dies + with "Trap 0x02 while interrupts disabled, Error state". Letting the + breakpoint be inserted normally results in QEMU knowing about the GDB + breakpoint, and thus trap before the breakpoint instruction is executed. + (If GDB later needs to continue execution past the permanent breakpoint, + it manually increments the PC, thus avoiding executing the breakpoint + instruction.) */ if (bp_loc_is_permanent (loc)) - { - loc->inserted = 1; - loc->permanent = 1; - } + loc->permanent = 1; return loc; } @@ -8974,20 +8964,6 @@ bp_loc_is_permanent (struct bp_location *loc) gdb_assert (loc != NULL); - /* bp_call_dummy breakpoint locations are usually memory locations - where GDB just wrote a breakpoint instruction, making it look - as if there is a permanent breakpoint at that location. Considering - it permanent makes GDB rely on that breakpoint instruction to stop - the program, thus removing the need to insert its own breakpoint - there. This is normally expected to work, except that some versions - of QEMU (Eg: QEMU 2.0.0 for SPARC) just report a fatal problem (Trap - 0x02 while interrupts disabled, Error state) instead of reporting - a SIGTRAP. QEMU should probably be fixed, but in the interest of - compatibility with versions that behave this way, we always consider - bp_call_dummy breakpoint locations as non-permanent. */ - if (loc->owner->type == bp_call_dummy) - return 0; - cleanup = save_current_space_and_thread (); switch_to_program_space_and_thread (loc->pspace); @@ -12430,12 +12406,6 @@ update_global_location_list (enum ugll_insert_mode insert_mode) continue; } - /* Permanent breakpoint should always be inserted. */ - if (loc->permanent && ! loc->inserted) - internal_error (__FILE__, __LINE__, - _("allegedly permanent breakpoint is not " - "actually inserted")); - if (b->type == bp_hardware_watchpoint) loc_first_p = &wp_loc_first; else if (b->type == bp_read_watchpoint) @@ -12471,12 +12441,6 @@ update_global_location_list (enum ugll_insert_mode insert_mode) /* Clear the condition modification flag. */ loc->condition_changed = condition_unchanged; - - if (loc->inserted && !loc->permanent - && (*loc_first_p)->permanent) - internal_error (__FILE__, __LINE__, - _("another breakpoint was inserted on top of " - "a permanent breakpoint")); } if (insert_mode == UGLL_INSERT || breakpoints_should_be_inserted_now ())