gdb: fix extended-remote restart
Seems versions of gdb > 6.8 require an W stop reply after receiving a kill packet. Without this we receive the following error from gdb: gdb/thread.c:72: internal-error: inferior_thread: Assertion `tp' failed. Change-Id: I86765a321f0429c9b517fe13ded0ee2dbd4b2f87 Signed-off-by: Spencer Oliver <spen@spen-soft.co.uk> Reviewed-on: http://openocd.zylin.com/911 Tested-by: jenkins Reviewed-by: Joel Bodenmann <joel@unormal.org> Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com>
This commit is contained in:
parent
443197aff0
commit
98a41bca6e
|
@ -74,6 +74,11 @@ struct gdb_connection {
|
||||||
* can be replied immediately and a new GDB packet will be ready without delay
|
* can be replied immediately and a new GDB packet will be ready without delay
|
||||||
* (ca. 10% or so...). */
|
* (ca. 10% or so...). */
|
||||||
bool mem_write_error;
|
bool mem_write_error;
|
||||||
|
/* with extended-remote it seems we need to better emulate attach/detach.
|
||||||
|
* what this means is we reply with a W stop reply after a kill packet,
|
||||||
|
* normally we reply with a S reply via gdb_last_signal_packet.
|
||||||
|
* as a side note this behaviour only effects gdb > 6.8 */
|
||||||
|
bool attached;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -762,6 +767,7 @@ static int gdb_new_connection(struct connection *connection)
|
||||||
gdb_connection->noack_mode = 0;
|
gdb_connection->noack_mode = 0;
|
||||||
gdb_connection->sync = true;
|
gdb_connection->sync = true;
|
||||||
gdb_connection->mem_write_error = false;
|
gdb_connection->mem_write_error = false;
|
||||||
|
gdb_connection->attached = true;
|
||||||
|
|
||||||
/* send ACK to GDB for debug request */
|
/* send ACK to GDB for debug request */
|
||||||
gdb_write(connection, "+", 1);
|
gdb_write(connection, "+", 1);
|
||||||
|
@ -878,9 +884,17 @@ static int gdb_last_signal_packet(struct connection *connection,
|
||||||
char *packet, int packet_size)
|
char *packet, int packet_size)
|
||||||
{
|
{
|
||||||
struct target *target = get_target_from_connection(connection);
|
struct target *target = get_target_from_connection(connection);
|
||||||
|
struct gdb_connection *gdb_con = connection->priv;
|
||||||
char sig_reply[4];
|
char sig_reply[4];
|
||||||
int signal_var;
|
int signal_var;
|
||||||
|
|
||||||
|
if (!gdb_con->attached) {
|
||||||
|
/* if we are here we have received a kill packet
|
||||||
|
* reply W stop reply otherwise gdb gets very unhappy */
|
||||||
|
gdb_put_packet(connection, "W00", 3);
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
signal_var = gdb_last_signal(target);
|
signal_var = gdb_last_signal(target);
|
||||||
|
|
||||||
snprintf(sig_reply, 4, "S%2.2x", signal_var);
|
snprintf(sig_reply, 4, "S%2.2x", signal_var);
|
||||||
|
@ -2160,8 +2174,10 @@ static int gdb_input_inner(struct connection *connection)
|
||||||
return retval;
|
return retval;
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
if (extended_protocol != 0)
|
if (extended_protocol != 0) {
|
||||||
|
gdb_con->attached = false;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
gdb_put_packet(connection, "OK", 2);
|
gdb_put_packet(connection, "OK", 2);
|
||||||
return ERROR_SERVER_REMOTE_CLOSED;
|
return ERROR_SERVER_REMOTE_CLOSED;
|
||||||
case '!':
|
case '!':
|
||||||
|
@ -2175,6 +2191,8 @@ static int gdb_input_inner(struct connection *connection)
|
||||||
watchpoint_clear_target(gdb_service->target);
|
watchpoint_clear_target(gdb_service->target);
|
||||||
command_run_linef(connection->cmd_ctx, "ocd_gdb_restart %s",
|
command_run_linef(connection->cmd_ctx, "ocd_gdb_restart %s",
|
||||||
target_name(target));
|
target_name(target));
|
||||||
|
/* set connection as attached after reset */
|
||||||
|
gdb_con->attached = true;
|
||||||
/* info rtos parts */
|
/* info rtos parts */
|
||||||
gdb_thread_packet(connection, packet, packet_size);
|
gdb_thread_packet(connection, packet, packet_size);
|
||||||
gdb_put_packet(connection, "OK", 2);
|
gdb_put_packet(connection, "OK", 2);
|
||||||
|
|
Loading…
Reference in New Issue