Hi, Currently, GDB assumes there can only be one stop_bpstat. This is OK in all-stop mode, as there can only be one even that the user has to care for. There are two uses of stop_bpstat outside of infrun.c, that is, outside of the path that handles an event. The first, is in infcmd.c:continue_command, where we implement setting a proceed count on the breakpoint we're stopped at: (gdb) help continue Continue program being debugged, after signal or breakpoint. If proceeding from breakpoint, a number N may be used as an argument, which means to set the ignore count of that breakpoint to N - 1 (so that the breakpoint won't break until the Nth time it is reached). /* If have argument (besides '&'), set proceed count of breakpoint we stopped at. */ if (proc_count_exp != NULL) { bpstat bs = stop_bpstat; int num, stat; int stopped = 0; while ((stat = bpstat_num (&bs, &num)) != 0) if (stat > 0) { set_ignore_count (num, parse_and_eval_long (proc_count_exp) - 1, from_tty); /* set_ignore_count prints a message ending with a period. So print two spaces before "Continuing.". */ if (from_tty) printf_filtered (" "); stopped = 1; } if (!stopped && from_tty) { printf_filtered ("Not stopped at any breakpoint; argument ignored.\n"); } } I had missed this on the non-stop series. I'll need to context switch stop_bpstat in non-stop mode, because there, we'll have simultaneous independant stop events, one per thread, and each should have its own stop_bpstat. That's a small change to patch 4 in series I posted. The second place is in breakpoints.c:delete_breakpoint. When we delete a breakpoint, we're looking through the stop_bpstat chain for a matching breakpoint, so we can clear the location from it: void delete_breakpoint (struct breakpoint *bpt) { ... /* Be sure no bpstat's are pointing at it after it's been freed. */ /* FIXME, how can we find all bpstat's? We just check stop_bpstat for now. Note that we cannot just remove bpstats pointing at bpt from the stop_bpstat list entirely, as breakpoint commands are associated with the bpstat; if we remove it here, then the later call to bpstat_do_actions (&stop_bpstat); in event-top.c won't do anything, and temporary breakpoints with commands won't work. */ for (bs = stop_bpstat; bs; bs = bs->next) if (bs->breakpoint_at && bs->breakpoint_at->owner == bpt) { bs->breakpoint_at = NULL; bs->old_val = NULL; /* bs->commands will be freed later. */ } ... } (Nevermind that bs->old_val is leaking.) Now, if we make a stop_bpstat per-thread, due to context-switching this will only update the stop_stat that corresponds to the current thread, leaving the stop_bpstats of the other threads, if stopped at the breakpoint we're deleting, with dangling pointers. One way to fix it, would be to also loop through all threads to update their version of stop_bpstat, but I'd like better. Another form, is to remove the dependency on knowing about stop_bpstat at all. That is what this patch implements. To do that, I added reference counting to bp_locations, and made sure the counts are updated at the appropriate places. To mark the location as ready for garbage collection, I've added a new bp_loc_dead location type. Does this look sane? I've tested this on x86_64-unknown-linux with and without breakpoints always-inserted on, without any regressions. -- Pedro Alves