Index: gdb/breakpoint.c =================================================================== RCS file: /cvs/src/src/gdb/breakpoint.c,v retrieving revision 1.338 diff -u -p -r1.338 breakpoint.c --- gdb/breakpoint.c 28 Jul 2008 17:53:52 -0000 1.338 +++ gdb/breakpoint.c 5 Aug 2008 20:32:55 -0000 @@ -1720,7 +1720,10 @@ 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) { @@ -3058,7 +3061,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) @@ -5100,6 +5104,22 @@ create_breakpoint (struct symtabs_and_li loc = add_location_to_breakpoint (b, type, &sal); } + /* Check if the location points to permanent breakpoint. */ + if (loc != NULL) + { + int len; + CORE_ADDR addr = loc->address; + const gdb_byte *brk = gdbarch_breakpoint_from_pc (current_gdbarch, + &addr, &len); + gdb_byte target_mem[32]; + if (!target_read_memory (loc->address, target_mem, len)) + { + /* We have the target memory here. */ + if (memcmp (target_mem, brk, len) == 0) + make_breakpoint_permanent (b); + } + } + if (b->cond_string) { char *arg = b->cond_string; @@ -7437,6 +7457,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; Index: gdb/i386-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/i386-tdep.c,v retrieving revision 1.261 diff -u -p -r1.261 i386-tdep.c --- gdb/i386-tdep.c 3 Jul 2008 00:19:58 -0000 1.261 +++ gdb/i386-tdep.c 5 Aug 2008 20:32:55 -0000 @@ -2550,6 +2550,17 @@ i386_fetch_pointer_argument (struct fram return read_memory_unsigned_integer (sp + (4 * (argi + 1)), 4); } +/* On i386, breakpoint is exactly 1 byte long, so we just + adjust the PC in the regcache. */ +static void +i386_skip_permanent_breakpoint (struct regcache *regcache) +{ + CORE_ADDR current_pc = regcache_read_pc (regcache); + current_pc += 1; + regcache_write_pc (regcache, current_pc); +} + + static struct gdbarch * i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) @@ -2738,6 +2749,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; }