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:
parent
976f8eef23
commit
1f487ee9b8
25
gdbstub.c
25
gdbstub.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue