Bug 12228 - thread.c:598: internal-error: is_thread_state: Assertion `tp' failed.
Summary: thread.c:598: internal-error: is_thread_state: Assertion `tp' failed.
Status: NEW
Alias: None
Product: gdb
Classification: Unclassified
Component: remote (show other bugs)
Version: 7.2
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-11-18 13:18 UTC by jon
Modified: 2018-09-27 18:51 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description jon 2010-11-18 13:18:20 UTC
When debugging an extended-remote target that automatically restarts after exiting, GDB will abort with:

thread.c:598: internal-error: is_thread_state: Assertion `tp' failed. 

when the thread exits. This appears to be due to the code in remote.c:extended_remote_mourn_1()

The code is:

	      /* Assume that the target has been restarted.  Set inferior_ptid
		 so that bits of core GDB realizes there's something here, e.g.,
		 so that the user can say "kill" again.	 */
	      inferior_ptid = magic_null_ptid;  

The problem is that this code sets a ptid, but thread_list is null (presumably because the thread has been removed due to it exiting), so when is_thread_state() is called at some later time, it looks for the magic_null_ptid thread in thread_list, but it can't find it, which results in the assertion failure.

One possiblity to fix this would be to create a thread, by adding the following after the code above:

              inferior_ptid = remote_current_thread (inferior_ptid);              
              remote_add_inferior (ptid_get_pid (inferior_ptid), -1);
              add_thread_silent (inferior_ptid);
Comment 1 Andrew Burgess 2011-03-25 15:25:55 UTC
There are further problems that the previous patch doesn't fix, if after killing the remote target that then restarts you might be tempted to try "info program" or "info threads" both of these will run into similar problems.

The patch below uses the remote_start_remote method in the same way as when we initially connect to the target to setup the thread state.

diff -u -p -r1.10 -r1.11
--- ./binutils/gdb/remote.c	27 Oct 2010 16:33:30 -0000	1.10
+++ ./binutils/gdb/remote.c	25 Mar 2011 15:13:01 -0000	1.11
@@ -6674,10 +6674,25 @@ extended_remote_mourn_1 (struct target_o
 
 	  if (rs->buf[0] == 'S' || rs->buf[0] == 'T')
 	    {
-	      /* Assume that the target has been restarted.  Set inferior_ptid
-		 so that bits of core GDB realizes there's something here, e.g.,
-		 so that the user can say "kill" again.	 */
-	      inferior_ptid = magic_null_ptid;
+              /* APB: 25-March-2010: Fix for issue TLFIREPATH-2263.
+                 When we kill the remote target the target is actual
+                 reset, and then enters the stop state, just like
+                 when we originally connect to it - we want the
+                 threads to reflect that.  */
+              struct gdb_exception ex;
+              struct start_remote_args args;
+              
+              args.from_tty = 0;
+              args.target = target;
+              args.extended_p = 1;
+
+              printf_filtered (_("Remote target reset.\n"));
+
+	      /* Assume that the target has been restarted. Attempt to
+                 restart the target.  */
+              ex = catch_exception (uiout, remote_start_remote, &args, RETURN_MASK_ALL);
+              if (ex.reason < 0)
+                throw_exception (ex);
 	    }
 	}
     }
Comment 2 Ben Longbons 2017-05-02 23:14:42 UTC
I hit this with a minimal example while filing another bug:

GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
@(gdb) target extended-remote | gdbserver --multi stdio
Remote debugging using | gdbserver --multi stdio
Remote debugging using stdio
@(gdb) set remote exec-file /bin/true
@(gdb) run
Starting program:  
Process /bin/true created; pid = 679
stdin/stdout redirected
Reading /bin/true from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /bin/true from remote target...
Reading symbols from target:/bin/true...Reading /bin/e82394864538fa7b23b7f87b259ea2a20889c4.debug from remote target...
Reading /bin/.debug/e82394864538fa7b23b7f87b259ea2a20889c4.debug from remote target...
(no debugging symbols found)...done.
/build/gdb-A87voC/gdb-7.12/gdb/thread.c:982: internal-error: int is_thread_state(ptid_t, thread_state): Assertion `tp' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
@Quit this debugging session? (y or n) y

This is a bug, please report it.  For instructions, see:
<http://www.gnu.org/software/gdb/bugs/>.

/build/gdb-A87voC/gdb-7.12/gdb/thread.c:982: internal-error: int is_thread_state(ptid_t, thread_state): Assertion `tp' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
@Create a core file of GDB? (y or n) y
[1]    669 abort (core dumped)  gdb


For this case, adding `file /bin/true` fixes it.
Comment 3 Trent Piepho 2018-09-27 18:51:43 UTC
I can duplicate this failure using gdb 8.0.1 and remote cross debugging as in the minimal example from comment 2.

However, in gdb 8.1.1, this appears fixed.  There was a significant change to the extended-remote code after 8.0.