This is the patch that split the notion of the frontend selected thread and frame from inferior_ptid. I've come to the conclusion this is the path to go for several reasons. - In non-stop mode, the user/frontend will have a stopped thread and frame selected, while a new event in another thread comes along. (Aside from having GDB switch threads automatically or not when another thread stops, ) this may just be an internal event. The user should not lose its selection. More on that below. - We avoided deleting inferior_ptid until the target stopped. This worked in all-stopped mode, as there, the user is not be able to enter commands that apply to the thread that has already exited. This split make it safe to notify the threads module that inferior_ptid exited. If we don't split the external/internal thread notion, then cases like switching threads and restoring the previous thread with a cleanup are tricky, because there is no reference anywhere to which thread was the previous one, other than inside the cleanup. Comparing with inferior_ptid only doesn't cut it. - The frontend wants to be reported of thread and frame changes that are interesting to the user, not every internal thread and selected frame change, used, e.g., while updating var-objects. The patch then updates the behaviour of GDB on the case of the selected thread exiting.  It implements a scheme similar to c) of the options listed here: http://sourceware.org/ml/gdb/2008-06/msg00013.html This requires some explanation, so here goes. After having tried solutions   b) (keep dead threads on the list, until the user switches threads) and   c) (don't keep dead threads on the list and make inferior_ptid point     to some magic ptid if inferior_ptid exits), and several combinations of the above, including one that added a new field to ptid (so dead threads would not match ptids comming from the events from the target layer), I came to the conclusion that there was something wrong with the way GDB manages the current user/frontend/external thread. Overloading inferior_ptid to mean the current thread/process that GDB is internally operating on, and also the user selected thread is really not what we want.  It was OK in all-stop mode, but is not ideal in non-stop. So, what the patch does is upgrade previous_inferior_ptid (which already played a small role in the "hey, I've switched to a new thread" business) to represent the external/user selected thread, rename it to user_selected_ptid, and add companion user_selected_frame and user_selected_frame_level, which are used to represent the frame the user has selected. The new store_selected_thread_and_frame is used to store the record which thread and frame the user/frontend has selected, and restore_selected_thread_and_frame is used to switch inferior_ptid and its selected frame to point back to what the user/frontend expects. With this patch in place, the target side can now call delete_thread without caring if inferior_ptid points to it.  The common code will take care of not deleting it just immediatelly, and still tagging/notifying of its exit.  It will be deleted whenever it's safe. thread_info's running state also gets a small upgrade into an enum that stores the running/stopped/exited state. If add_thread* is called, and the ptid being added is already listed, it means the OS is reusing the tid.  In that case, we delete the old ptid from the list, and add the new one --- this new one will get a new GDB thread num.  If the thread just exiting was also the user selected thread, we invalidate it. This means that in all-stop, if the OS is reusing the selected thread's ptid, and this new thread has the next event, normal_stop will now notice that this is a new thread, and print a "switched to thread" notice, although the ptid didn't change (if we added the GDB thread num to that output, the user could notice the change). I've added three points where GDB makes the internal (inferior_ptid) thread switch to the user selected thread (user_selected_ptid):  1 - execute_command, before executing a command  2 - execute_command, after executing a command,  3 - fetch_inferior_event, after handling the event. With these in place, the user never notices when GDB switches between threads internally while handing events. You'll also notice that the implementations of "info threads", "thread apply all/tid" and a couple of other places get a clean up, since now execute_command takes care of restoring the user selected thread and frame. In the case were we want to temporarily execute a command to a thread other than the current thread, we switch the internal thread to the thread we want with switch_to_thread/context_switch_to, and invoke execute_command_internal.  Unlike execute_command, this doesn't re-switch the internal thread to the external thread. There are examples in thread_apply_all_command, and thread_apply_command.  This can be used to implement the "--thread" switch in MI commands. Oh, and here's what happens when the current thread exits in non-stop mode: (gdb) b 81 Breakpoint 1 at 0x80485fd: file threads.c, line 81. (gdb) r Starting program: /home/pedro/gdb/tests/threads32 [Thread debugging using libthread_db enabled] [New Thread 0xf7e22b90 (LWP 29573)] [New Thread 0xf7621b90 (LWP 29574)] Breakpoint 1, thread_function1 (arg=0x1) at threads.c:81 81              usleep (1);  /* Loop increment.  */ Thread 3 [Thread 0xf7621b90 (LWP 29574)] stopped (gdb) thread 3 [Switching to thread 3 (Thread 0xf7621b90 (LWP 29574))]#0  thread_function1 (arg=0x1) at threads.c:81 81              usleep (1);  /* Loop increment.  */ (gdb) info threads * 3 Thread 0xf7621b90 (LWP 29574)  thread_function1 (arg=0x1) at threads.c:81   2 Thread 0xf7e22b90 (LWP 29573)  (running)   1 Thread 0xf7e236b0 (LWP 29570)  (running) (gdb) p *myp=0 $1 = 0 (gdb) c& Continuing. (gdb) [Thread 0xf7621b90 (LWP 29574) exited] info threads   2 Thread 0xf7e22b90 (LWP 29573)  (running)   1 Thread 0xf7e236b0 (LWP 29570)  (running) No selected thread.  See `help thread' (gdb) p a Cannot execute this command without a selected thread.  See `help thread' (gdb) thread 2 [Switching to thread 2 (Thread 0xf7e22b90 (LWP 29573))](running) (gdb) info threads * 2 Thread 0xf7e22b90 (LWP 29573)  (running)   1 Thread 0xf7e236b0 (LWP 29570)  (running) (gdb) p a Cannot execute this command while the target is running. (gdb) interrupt (gdb) Program received signal SIGINT, Interrupt. 0xffffe410 in __kernel_vsyscall () info threads * 2 Thread 0xf7e22b90 (LWP 29573)  0xffffe410 in __kernel_vsyscall ()   1 Thread 0xf7e236b0 (LWP 29570)  (running) (gdb) p a No symbol "a" in current context. (gdb) -- Pedro Alves