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>
* can be replied immediately and a new GDB packet will be ready without delay
* (ca. 10% or so...). */
bool mem_write_error;
* can be replied immediately and a new GDB packet will be ready without delay
* (ca. 10% or so...). */
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;
gdb_connection->noack_mode = 0;
gdb_connection->sync = true;
gdb_connection->mem_write_error = false;
gdb_connection->noack_mode = 0;
gdb_connection->sync = true;
gdb_connection->mem_write_error = false;
+ gdb_connection->attached = true;
/* send ACK to GDB for debug request */
gdb_write(connection, "+", 1);
/* send ACK to GDB for debug request */
gdb_write(connection, "+", 1);
char *packet, int packet_size)
{
struct target *target = get_target_from_connection(connection);
char *packet, int packet_size)
{
struct target *target = get_target_from_connection(connection);
+ struct gdb_connection *gdb_con = connection->priv;
char sig_reply[4];
int signal_var;
char sig_reply[4];
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);
snprintf(sig_reply, 4, "S%2.2x", signal_var);
signal_var = gdb_last_signal(target);
snprintf(sig_reply, 4, "S%2.2x", signal_var);
return retval;
break;
case 'k':
return retval;
break;
case 'k':
- if (extended_protocol != 0)
+ if (extended_protocol != 0) {
+ gdb_con->attached = false;
gdb_put_packet(connection, "OK", 2);
return ERROR_SERVER_REMOTE_CLOSED;
case '!':
gdb_put_packet(connection, "OK", 2);
return ERROR_SERVER_REMOTE_CLOSED;
case '!':
watchpoint_clear_target(gdb_service->target);
command_run_linef(connection->cmd_ctx, "ocd_gdb_restart %s",
target_name(target));
watchpoint_clear_target(gdb_service->target);
command_run_linef(connection->cmd_ctx, "ocd_gdb_restart %s",
target_name(target));
+ /* set connection as attached after reset */
+ gdb_con->attached = true;
/* info rtos parts */
gdb_thread_packet(connection, packet, packet_size);
gdb_put_packet(connection, "OK", 2);
/* info rtos parts */
gdb_thread_packet(connection, packet, packet_size);
gdb_put_packet(connection, "OK", 2);