Commit 1f487ee9b8e502c4153f10ce6aa99e1da33df9e9
1 parent
976f8eef
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
Showing
1 changed file
with
19 additions
and
6 deletions
gdbstub.c
... | ... | @@ -65,6 +65,7 @@ typedef struct GDBState { |
65 | 65 | int line_csum; |
66 | 66 | uint8_t last_packet[4100]; |
67 | 67 | int last_packet_len; |
68 | + int signal; | |
68 | 69 | #ifdef CONFIG_USER_ONLY |
69 | 70 | int fd; |
70 | 71 | int running_state; |
... | ... | @@ -93,9 +94,13 @@ static int get_char(GDBState *s) |
93 | 94 | for(;;) { |
94 | 95 | ret = recv(s->fd, &ch, 1, 0); |
95 | 96 | if (ret < 0) { |
97 | + if (errno == ECONNRESET) | |
98 | + s->fd = -1; | |
96 | 99 | if (errno != EINTR && errno != EAGAIN) |
97 | 100 | return -1; |
98 | 101 | } else if (ret == 0) { |
102 | + close(s->fd); | |
103 | + s->fd = -1; | |
99 | 104 | return -1; |
100 | 105 | } else { |
101 | 106 | break; |
... | ... | @@ -991,6 +996,10 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) |
991 | 996 | } |
992 | 997 | gdb_continue(s); |
993 | 998 | return RS_IDLE; |
999 | + case 'C': | |
1000 | + s->signal = strtoul(p, (char **)&p, 16); | |
1001 | + gdb_continue(s); | |
1002 | + return RS_IDLE; | |
994 | 1003 | case 'k': |
995 | 1004 | /* Kill the target */ |
996 | 1005 | fprintf(stderr, "\nQEMU: Terminated via GDBstub\n"); |
... | ... | @@ -1364,10 +1373,9 @@ gdb_handlesig (CPUState *env, int sig) |
1364 | 1373 | char buf[256]; |
1365 | 1374 | int n; |
1366 | 1375 | |
1367 | - if (gdbserver_fd < 0) | |
1368 | - return sig; | |
1369 | - | |
1370 | 1376 | s = &gdbserver_state; |
1377 | + if (gdbserver_fd < 0 || s->fd < 0) | |
1378 | + return sig; | |
1371 | 1379 | |
1372 | 1380 | /* disable single step if it was enabled */ |
1373 | 1381 | cpu_single_step(env, 0); |
... | ... | @@ -1378,6 +1386,10 @@ gdb_handlesig (CPUState *env, int sig) |
1378 | 1386 | snprintf(buf, sizeof(buf), "S%02x", sig); |
1379 | 1387 | put_packet(s, buf); |
1380 | 1388 | } |
1389 | + /* put_packet() might have detected that the peer terminated the | |
1390 | + connection. */ | |
1391 | + if (s->fd < 0) | |
1392 | + return sig; | |
1381 | 1393 | |
1382 | 1394 | sig = 0; |
1383 | 1395 | s->state = RS_IDLE; |
... | ... | @@ -1398,6 +1410,8 @@ gdb_handlesig (CPUState *env, int sig) |
1398 | 1410 | return sig; |
1399 | 1411 | } |
1400 | 1412 | } |
1413 | + sig = s->signal; | |
1414 | + s->signal = 0; | |
1401 | 1415 | return sig; |
1402 | 1416 | } |
1403 | 1417 | |
... | ... | @@ -1407,10 +1421,9 @@ void gdb_exit(CPUState *env, int code) |
1407 | 1421 | GDBState *s; |
1408 | 1422 | char buf[4]; |
1409 | 1423 | |
1410 | - if (gdbserver_fd < 0) | |
1411 | - return; | |
1412 | - | |
1413 | 1424 | s = &gdbserver_state; |
1425 | + if (gdbserver_fd < 0 || s->fd < 0) | |
1426 | + return; | |
1414 | 1427 | |
1415 | 1428 | snprintf(buf, sizeof(buf), "W%02x", code); |
1416 | 1429 | put_packet(s, buf); | ... | ... |