Support signal reception in user-mode. Handle when the peer terminates or aborts the connection.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4483 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
edgar_igl 2008-05-17 22:20:53 +00:00
parent 976f8eef23
commit 1f487ee9b8
1 changed files with 19 additions and 6 deletions

View File

@ -65,6 +65,7 @@ typedef struct GDBState {
int line_csum; int line_csum;
uint8_t last_packet[4100]; uint8_t last_packet[4100];
int last_packet_len; int last_packet_len;
int signal;
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
int fd; int fd;
int running_state; int running_state;
@ -93,9 +94,13 @@ static int get_char(GDBState *s)
for(;;) { for(;;) {
ret = recv(s->fd, &ch, 1, 0); ret = recv(s->fd, &ch, 1, 0);
if (ret < 0) { if (ret < 0) {
if (errno == ECONNRESET)
s->fd = -1;
if (errno != EINTR && errno != EAGAIN) if (errno != EINTR && errno != EAGAIN)
return -1; return -1;
} else if (ret == 0) { } else if (ret == 0) {
close(s->fd);
s->fd = -1;
return -1; return -1;
} else { } else {
break; break;
@ -991,6 +996,10 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
} }
gdb_continue(s); gdb_continue(s);
return RS_IDLE; return RS_IDLE;
case 'C':
s->signal = strtoul(p, (char **)&p, 16);
gdb_continue(s);
return RS_IDLE;
case 'k': case 'k':
/* Kill the target */ /* Kill the target */
fprintf(stderr, "\nQEMU: Terminated via GDBstub\n"); fprintf(stderr, "\nQEMU: Terminated via GDBstub\n");
@ -1364,10 +1373,9 @@ gdb_handlesig (CPUState *env, int sig)
char buf[256]; char buf[256];
int n; int n;
if (gdbserver_fd < 0)
return sig;
s = &gdbserver_state; s = &gdbserver_state;
if (gdbserver_fd < 0 || s->fd < 0)
return sig;
/* disable single step if it was enabled */ /* disable single step if it was enabled */
cpu_single_step(env, 0); cpu_single_step(env, 0);
@ -1378,6 +1386,10 @@ gdb_handlesig (CPUState *env, int sig)
snprintf(buf, sizeof(buf), "S%02x", sig); snprintf(buf, sizeof(buf), "S%02x", sig);
put_packet(s, buf); put_packet(s, buf);
} }
/* put_packet() might have detected that the peer terminated the
connection. */
if (s->fd < 0)
return sig;
sig = 0; sig = 0;
s->state = RS_IDLE; s->state = RS_IDLE;
@ -1398,6 +1410,8 @@ gdb_handlesig (CPUState *env, int sig)
return sig; return sig;
} }
} }
sig = s->signal;
s->signal = 0;
return sig; return sig;
} }
@ -1407,10 +1421,9 @@ void gdb_exit(CPUState *env, int code)
GDBState *s; GDBState *s;
char buf[4]; char buf[4];
if (gdbserver_fd < 0)
return;
s = &gdbserver_state; s = &gdbserver_state;
if (gdbserver_fd < 0 || s->fd < 0)
return;
snprintf(buf, sizeof(buf), "W%02x", code); snprintf(buf, sizeof(buf), "W%02x", code);
put_packet(s, buf); put_packet(s, buf);