Commit 1f487ee9b8e502c4153f10ce6aa99e1da33df9e9

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