Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions debugger/breakpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
/* The current breakpoints */
GSList *debugger_breakpoints;

volatile int debugger_breakpoints_remove_pending = 0;

/* The next breakpoint ID to use */
static size_t next_breakpoint_id;

Expand Down Expand Up @@ -237,6 +239,11 @@ debugger_check( debugger_breakpoint_type type, libspectrum_dword value )

int signal_breakpoints_updated = 0;

if( debugger_breakpoints_remove_pending ) {
debugger_breakpoints_remove_pending = 0;
debugger_breakpoint_remove_all();
}

switch( debugger_mode ) {

case DEBUGGER_MODE_INACTIVE: return 0;
Expand Down
5 changes: 5 additions & 0 deletions debugger/debugger_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ extern int debugger_memory_pool;
/* The event type used to trigger time breakpoints */
extern int debugger_breakpoint_event;

/* Set by the gdbserver network thread when a client disconnects while the
emulator is running; honoured by debugger_check() on the emulator thread so
the breakpoint list is never freed underneath an in-progress walk. */
extern volatile int debugger_breakpoints_remove_pending;

void debugger_breakpoint_time_fn( libspectrum_dword tstates, int type, void *user_data );

int debugger_breakpoint_remove( size_t id );
Expand Down
11 changes: 9 additions & 2 deletions debugger/gdbserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -736,8 +736,15 @@ static void* network_thread(void* arg)
while ((ret = process_network(gdbserver_client_socket)) == 0) ;
printf("Socket closed: %d\n", gdbserver_client_socket);

debugger_breakpoint_remove_all();
printf("Deleted all breakpoints.\n");
/* Remove the client's breakpoints without racing the emulator's
debugger_check() walk: free directly only while the emulator is
parked in the trap loop; otherwise defer the free to the emulator
thread, which performs it from debugger_check(). */
if (gdbserver_trapped) {
debugger_breakpoint_remove_all();
} else {
debugger_breakpoints_remove_pending = 1;
}

compat_socket_close(gdbserver_client_socket);
gdbserver_client_socket = -1;
Expand Down
Loading