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); | ... | ... |