Index: gdb/breakpoint.c =================================================================== RCS file: /cvs/src/src/gdb/breakpoint.c,v retrieving revision 1.345 diff -u -p -r1.345 breakpoint.c --- gdb/breakpoint.c 26 Aug 2008 17:36:44 -0000 1.345 +++ gdb/breakpoint.c 2 Sep 2008 15:17:15 -0000 @@ -1750,7 +1750,8 @@ breakpoint_init_inferior (enum inf_conte struct bp_location *bpt; ALL_BP_LOCATIONS (bpt) - bpt->inserted = 0; + if (bpt->owner->enable_state != bp_permanent) + bpt->inserted = 0; ALL_BREAKPOINTS_SAFE (b, temp) { @@ -3088,7 +3089,8 @@ bpstat_stop_status (CORE_ADDR bp_addr, p /* We will stop here */ if (b->disposition == disp_disable) { - b->enable_state = bp_disabled; + if (b->enable_state != bp_permanent) + b->enable_state = bp_disabled; update_global_location_list (0); } if (b->silent) @@ -5081,6 +5083,34 @@ add_location_to_breakpoint (struct break set_breakpoint_location_function (loc); return loc; } + + +/* Return 1 if LOC is pointing to a permanent breakpoint, + return 0 otherwise. */ + +static int +bp_loc_is_permanent (struct bp_location *loc) +{ + int len; + CORE_ADDR addr; + const gdb_byte *brk; + gdb_byte *target_mem; + + gdb_assert (loc != NULL); + + addr = loc->address; + brk = gdbarch_breakpoint_from_pc (current_gdbarch, &addr, &len); + + target_mem = alloca (len); + + if (target_read_memory (loc->address, target_mem, len) == 0 + && memcmp (target_mem, brk, len) == 0) + return 1; + + return 0; +} + + /* Create a breakpoint with SAL as location. Use ADDR_STRING as textual description of the location, and COND_STRING @@ -5135,6 +5165,9 @@ create_breakpoint (struct symtabs_and_li loc = add_location_to_breakpoint (b, type, &sal); } + if (bp_loc_is_permanent (loc)) + make_breakpoint_permanent (b); + if (b->cond_string) { char *arg = b->cond_string; @@ -7389,6 +7422,10 @@ update_breakpoint_locations (struct brea b->line_number = sals.sals[i].line; } + /* Update locationos of permanent breakpoints. */ + if (b->enable_state == bp_permanent) + make_breakpoint_permanent (b); + /* If possible, carry over 'disable' status from existing breakpoints. */ { struct bp_location *e = existing_locations; @@ -8152,6 +8189,7 @@ single_step_breakpoint_inserted_here_p ( return 0; } + /* This help string is used for the break, hbreak, tbreak and thbreak commands. It is defined as a macro to prevent duplication. Index: gdb/i386-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/i386-tdep.c,v retrieving revision 1.264 diff -u -p -r1.264 i386-tdep.c --- gdb/i386-tdep.c 26 Aug 2008 17:40:24 -0000 1.264 +++ gdb/i386-tdep.c 2 Sep 2008 15:17:16 -0000 @@ -2624,6 +2624,18 @@ i386_fetch_pointer_argument (struct fram return read_memory_unsigned_integer (sp + (4 * (argi + 1)), 4); } +static void +i386_skip_permanent_breakpoint (struct regcache *regcache) +{ + CORE_ADDR current_pc = regcache_read_pc (regcache); + + /* On i386, breakpoint is exactly 1 byte long, so we just + adjust the PC in the regcache. */ + current_pc += 1; + regcache_write_pc (regcache, current_pc); +} + + static struct gdbarch * i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) @@ -2812,6 +2824,9 @@ i386_gdbarch_init (struct gdbarch_info i if (tdep->mm0_regnum == 0) tdep->mm0_regnum = gdbarch_num_regs (gdbarch); + set_gdbarch_skip_permanent_breakpoint (gdbarch, + i386_skip_permanent_breakpoint); + return gdbarch; }