revision 1271:3edc4bdd7c0b
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 1271:3edc4bdd7c0b |
parent | 1270:65fd19c07e2e |
child | 1272:0b947d924029 |
author | nkeynes |
date | Thu Mar 15 08:26:06 2012 +1000 (12 years ago) |
GDB: Support ^C interruption from GDB
- postpone dreamcast_run() until after the IO callback returns (callback
won't be called again until the callback returns, so blocks all input)
- generate stop notifications when the DC stops, regardless of where the
stop originates.
- postpone dreamcast_run() until after the IO callback returns (callback
won't be called again until the callback returns, so blocks all input)
- generate stop notifications when the DC stops, regardless of where the
stop originates.
src/gdbserver.c | view | annotate | diff | log |
1.1 --- a/src/gdbserver.c Thu Mar 15 08:21:22 2012 +10001.2 +++ b/src/gdbserver.c Thu Mar 15 08:26:06 2012 +10001.3 @@ -26,9 +26,11 @@1.4 #include <glib.h>1.5 #include <arpa/inet.h>1.6 #include "lxdream.h"1.7 +#include "dream.h"1.8 #include "dreamcast.h"1.9 #include "ioutil.h"1.10 #include "cpu.h"1.11 +#include "gui.h"1.13 #define DEFAULT_BUFFER_SIZE 10241.14 #define BUFFER_SIZE_MARGIN 321.15 @@ -50,9 +52,12 @@1.16 int buf_posn;1.17 };1.19 +static GList *gdb_server_conn_list = NULL;1.20 +1.21 void gdb_server_free( gpointer data )1.22 {1.23 struct gdb_server *server = (struct gdb_server *)data;1.24 + gdb_server_conn_list = g_list_remove(gdb_server_conn_list, server);1.25 free((char *)server->peer_name);1.26 free(server->buf);1.27 free(data);1.28 @@ -209,8 +214,7 @@1.29 gdb_send_frame( server, "S05", 3 );1.30 break;1.31 case 'c': /* Continue */1.32 - dreamcast_run();1.33 - gdb_send_frame( server, "S05", 3 );1.34 + gui_do_later(dreamcast_run);1.35 break;1.36 case 'g': /* Read all general registers */1.37 gdb_print_registers( server, buf, sizeof(buf), 0, server->cpu->num_gpr_regs );1.38 @@ -422,6 +426,10 @@1.39 continue;1.40 } else if( server->buf[i] == '-' ) {1.41 /* Request retransmit */1.42 + } else if( server->buf[i] == '\003' ) { /* Control-C */1.43 + if( dreamcast_is_running() ) {1.44 + dreamcast_stop();1.45 + }1.46 } /* Anything else is noise */1.47 } else if( server->buf[i] == '#' ) {1.48 frame_len = i - frame_start - 1;1.49 @@ -496,11 +504,33 @@1.50 chan_serv->buf_size = 1024;1.51 chan_serv->buf_posn = 0;1.52 io_register_tcp_listener( conn_fd, gdb_server_data_callback, chan_serv, gdb_server_free );1.53 + gdb_server_conn_list = g_list_append(gdb_server_conn_list, chan_serv);1.54 INFO( "GDB connected from %s", chan_serv->peer_name );1.55 }1.56 return TRUE;1.57 }1.59 +void gdb_server_notify_stopped( struct gdb_server *server )1.60 +{1.61 + gdb_send_frame( server, "S05", 3 );1.62 +}1.63 +1.64 +/**1.65 + * stop handler to generate notifications to all connected clients1.66 + */1.67 +void gdb_server_on_stop()1.68 +{1.69 + GList *ptr;1.70 + for( ptr = gdb_server_conn_list; ptr != NULL; ptr = ptr->next ) {1.71 + gdb_server_notify_stopped( (struct gdb_server *)ptr->data );1.72 + }1.73 +}1.74 +1.75 +static gboolean module_registered = FALSE;1.76 +static struct dreamcast_module gdb_server_module = {1.77 + "gdbserver", NULL, NULL, NULL, NULL, gdb_server_on_stop, NULL, NULL };1.78 +1.79 +1.80 /**1.81 * Bind a network port for a GDB remote server for the specified cpu. The1.82 * port is registered for the system network callback.1.83 @@ -514,6 +544,11 @@1.84 */1.85 gboolean gdb_init_server( const char *interface, int port, cpu_desc_t cpu, gboolean mmu )1.86 {1.87 + if( !module_registered ) {1.88 + dreamcast_register_module( &gdb_server_module );1.89 + module_registered = TRUE;1.90 + }1.91 +1.92 int fd = io_create_server_socket( interface, port );1.93 if( fd == -1 ) {1.94 return FALSE;
.