This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: [RFA] gdb/win32-nat.c: do not call CloseHandle on process and thread handles


> 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 <windows.h>

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;
}



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]