From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19464 invoked by alias); 4 Jun 2008 00:53:41 -0000 Received: (qmail 19419 invoked by uid 22791); 4 Jun 2008 00:53:39 -0000 X-Spam-Check-By: sourceware.org Received: from imr1.ericy.com (HELO imr1.ericy.com) (198.24.6.9) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 04 Jun 2008 00:53:18 +0000 Received: from eusrcmw751.eamcs.ericsson.se (eusrcmw751.exu.ericsson.se [138.85.77.51]) by imr1.ericy.com (8.13.1/8.13.1) with ESMTP id m540rAEQ010899; Tue, 3 Jun 2008 19:53:10 -0500 Received: from ecamlmw720.eamcs.ericsson.se ([142.133.1.72]) by eusrcmw751.eamcs.ericsson.se with Microsoft SMTPSVC(6.0.3790.1830); Tue, 3 Jun 2008 19:53:09 -0500 Content-class: urn:content-classes:message MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Subject: RE: non-stop and current thread exiting Date: Wed, 04 Jun 2008 00:53:00 -0000 Message-ID: <6D19CA8D71C89C43A057926FE0D4ADAA04E1BD47@ecamlmw720.eamcs.ericsson.se> References: <200806032253.39575.pedro@codesourcery.com> From: "Marc Khouzam" To: "Pedro Alves" , Cc: "Francois Chouinard" , "Pawel Piech" X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2008-06/txt/msg00015.txt.bz2 Hi, so we all agree that a) is no good. b) and c) are good.=20=20 The advantage of b), as you point out, is that the user can see which thread was previously selected. However, since GDB will no longer be changing threads automatically, a frontend will already know which thread was previously selected. So, my first impression is that c) is actually better since it keeps 'info thread' looking the same. Having b) report a thread as (exited) will require the frontend to add extra intelligence to parse that. This may not be true from a user's point-of-view where she/he may not remember the previously selected thread. But I haven't figured out if the user would really care. In the case of b) or c) one point that is important for the=20 a frontend is how GDB will react to prohibited commands when no thread is selected? Will a prohibited command cause an ^error or maybe an empty ^done, or something else? At this time, I don't have a clear picture of how the frontend will behave in those cases so I'm not sure what is best yet... So, in short I vote for c), but b) would be acceptable too. Marc=20 -----Original Message----- From: Pedro Alves [mailto:pedro@codesourcery.com] Sent: Tue 6/3/2008 5:53 PM To: gdb@sourceware.org Cc: Marc Khouzam Subject: non-stop and current thread exiting =20 Hi all, Non-stop has currently one issue to resolve that I'd like your input on. With all stop, no command is allowed while the inferior is running. In sync mode, well, GDB isn't listenning to commands, in async mode, only a few commands are allowed, I think help, interrupt, dir, pwd, not much else. These are all commands safe to use. Imagine the case where you're debugging a multi-threaded app. There are 3 threads including the main thread. Thread 2 is selected. You issue continue, that thread exits, but GDB doesn't give the user the control then, the inferior is kept running. Finally, when some other thread hits a breakpoint GDB switches the user thread to it automatically. Hence, there was never a situation where the selected thread has already exited, on which case the user could issue commands to a dead thread. Now, enter non-stop. With non-stop, however, we'll want to be able to say for example "info threads" at any time (or -thread-info, in MI). Take this example: (gdb)l 75 volatile int *myp =3D (volatile int *) &args[my_number]; 76 77 /* Don't run forever. Run just short of it :) */ 78 while (*myp > 0) 79 { 80 (*myp) ++; 81 usleep (1); /* Loop increment. */ 82 // printf ("thread_function1: %d\n", *myp); 83 // fflush (stdout); 84 } (gdb)l 85 86 pthread_exit(NULL); 87 } (gdb) b 80 Breakpoint 1 at 0x80485f0: file threads.c, line 80. (gdb) r Starting program: /home/pedro/gdb/tests/threads32 [Thread debugging using libthread_db enabled] [New Thread 0xf7d5bb90 (LWP 8506)] [New Thread 0xf755ab90 (LWP 8507)] [Switching to Thread 0xf755ab90 (LWP 8507)] Breakpoint 1, thread_function1 (arg=3D0x1) at threads.c:80 80 (*myp) ++; (gdb) n& (gdb) 81 usleep (1); /* Loop increment. */ Now, let's let the selected thread exit. p *myp=3D0 $1 =3D 0 (gdb) c& Continuing. (gdb) [Thread 0xf755ab90 (LWP 8507) exited] At this point, which should be the selected thread, and what should "info threads" show? GDB isn't currently prepared for this situation, so with the last non-stop series I posted, several=20 commands issued at this point trigger internal assertions, because the current thread doesn't exist in the thread list. I see three possibilities to solve issues like these. a) Have GDB switch to an arbitrary thread when the current thread is gone. b) Leave the currently selected dead thread in the thread list, tag it as dead. Prohibit most commands but "thread" and "info threads" in this situation. Get rid of the dead thread as soon as the user/frontend switches to another thread. (gdb) info threads * 3 Thread 0xf755ab90 (LWP 8507) (exited) 2 Thread 0xf7d5bb90 (LWP 8506) (running) 1 Thread 0xf7d5c6b0 (LWP 8503) (running) Notice the "(exited)" mark. (gdb) print a The selected thread is no longer available. See `help thread' to change selected thread. Switching threads: (gdb) thread 2 [Switching to thread 2 (Thread 0xf7ddfb90 (LWP 10771))] (running) Ah, it's gone now: (gdb) info threads * 2 Thread 0xf7ddfb90 (LWP 10771) (running) 1 Thread 0xf7de06b0 (LWP 10766) (running) c) Allow deleting the current thread anyway, and have it not listed in the thread list. Do some internal magic, to point the current thread at some "already exited" special thread. Prohibit most commands but "thread" and "info threads" in this situation. Show something like this or similar in "info threads" (gdb) info threads 2 Thread 0xf7d5bb90 (LWP 8506) (running) 1 Thread 0xf7d5c6b0 (LWP 8503) (running) No selected thread. I like b) or c) because I prefer that GDB doesn't switch threads on me automatically. Having 'call ExitThread (1)' apply to the wrong thread, because GDB decided to switch threads on my back between `)' and `', is a race I'd like to avoid. b) has the disadvantage that code that iterates over threads may have to take care of not doing things to dead threads. I don't think there are many places. It has the advantage that the user can still see some info on which thread was last selected. c) has the advantage that code that iterates over threads, can still rely on a thread being ptid(-1) to mean it's dead. Easier to spot a bug. We can perhaps still show to the user which thread was selected by storing that info in some global: 2 Thread 0xf7d5bb90 (LWP 8506) (running) 1 Thread 0xf7d5c6b0 (LWP 8503) (running) The selected thread was 3, but it has exited. Please=20 change threads. We had a small internal discussion, and at the time there was concensus that b) would be the best option. What do you think? Do you see other options, or problems with b) ? Marc, could you share with us your thoughts, in the perspective of a non-stop frontend developer ? --=20 Pedro Alves