From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14941 invoked by alias); 22 Nov 2007 13:56:48 -0000 Received: (qmail 14932 invoked by uid 22791); 22 Nov 2007 13:56:47 -0000 X-Spam-Check-By: sourceware.org Received: from ics.u-strasbg.fr (HELO ics.u-strasbg.fr) (130.79.112.250) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 22 Nov 2007 13:56:41 +0000 Received: from ICSMULLER (laocoon.u-strasbg.fr [130.79.112.72]) by ics.u-strasbg.fr (Postfix) with ESMTP id 52E6618701A; Thu, 22 Nov 2007 15:01:12 +0100 (CET) From: "Pierre Muller" To: "'Pedro Alves'" Cc: References: <002801c82d06$21bdf510$6539df30$@u-strasbg.fr> <4053daab0711220456q46cca9b4m3714c35bcc805518@mail.gmail.com> In-Reply-To: <4053daab0711220456q46cca9b4m3714c35bcc805518@mail.gmail.com> Subject: RE: [RFA] gdb/win32-nat.c: do not call CloseHandle on process and thread handles Date: Thu, 22 Nov 2007 13:56:00 -0000 Message-ID: <002c01c82d0f$8c789050$a569b0f0$@u-strasbg.fr> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Office Outlook 12.0 Content-Language: en-us Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-11/txt/msg00409.txt.bz2 > You'll still have to somehow close this process handle (current_process_handle): > > /* Called in pathological case where Windows fails to send a > CREATE_PROCESS_DEBUG_EVENT after an attach. */ > static DWORD fake_create_process (void) { > current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, > current_event.dwProcessId); > main_thread_id = current_event.dwThreadId; > current_thread = win32_add_thread (main_thread_id, > current_event.u.CreateThread.hThread); > return main_thread_id; > } I don't think that anything in the testsuite checks this case. The only code location that calls this function has also some comment: case CREATE_THREAD_DEBUG_EVENT: DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n", (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId, "CREATE_THREAD_DEBUG_EVENT")); if (saw_create != 1) { if (!saw_create && attach_flag) { /* Kludge around a Windows bug where first event is a create thread event. Caused when attached process does not have a main thread. */ retval = ourstatus->value.related_pid = fake_create_process (); saw_create++; } But what does the wording 'does not have a main thread' mean? Is there a way to create such a process in order to try to find out how we need to solve this issue? I tried to modify your suspend source to exit the main thread before the secondary thread exists, but it is unclear to me if the main thread can really be terminated by a call to ExitThread. See modified source below. I do get a EXIT_THREAD_DEBUG_EVENT, (as can be seen if you use 'set debugevents 1') but get_win32_debug_event ignores this event if the id is equal to main_thread_id, so that the thread seems still valid for gdb. On the other hand, I tried to get the GetExitCodeThread, but this call always returns STILL_ACTIVE... Thus I could not create a win32 executable that has no main thread anymore... Does anyone have such a code ready? Concerning attached processes that send a CREATE_THREAD_DEBUG_EVENT first, is the CREATE_PROCESS_DEBUG_EVENT event still sent to debugger, but after the CREATE_THREAD_DEBUG_EVENT? In that case, it might be better to close the opened handle when the CREATE_PROCESS_DEBUG_EVENT arrives and switch current_process_handle to the handle value given at that time. Pierre Muller Modified code to try to get a program that has no main thread anymore: #include HANDLE started; HANDLE stop; HANDLE mainh; DWORD WINAPI thread_start (void *arg) { int i; SetEvent (started); WaitForSingleObject (stop, INFINITE); for (i=1;i<=1000;i++) { DWORD ex; Sleep(100); if (!GetExitCodeThread (mainh, &ex)) printf("GetExitCodeThread failed %d\n", GetLastError ()); else if (ex != STILL_ACTIVE) printf ("main thread exited with value %d\n", ex); printf("%d\n",i); } return 0; } int main (int argc, char **argv) { int i; DWORD suspend_count; started = CreateEvent (NULL, TRUE, FALSE, NULL); stop = CreateEvent (NULL, TRUE, FALSE, NULL); HANDLE h = CreateThread (NULL, 0, thread_start, NULL, 0, NULL); WaitForSingleObject (started, INFINITE); for (i = 0; i < 3; i++) if (SuspendThread (h) == (DWORD) -1) { printf ("SuspendThreadFailed\n"); return 1; } suspend_count = ResumeThread (h); /* set breakpoint here */ printf ("%lu\n", suspend_count); /* should be 3 */ while ((suspend_count = ResumeThread (h)) != 0 && suspend_count != -1) ; SetEvent (stop); // WaitForSingleObject (h, INFINITE); CloseHandle (h); CloseHandle (started); CloseHandle (stop); mainh = GetCurrentThread (); ExitThread (6); return 0; }