Add gdb.threads/leader-exit-schedlock.exp
This adds a new test for letting the main thread exit the process with
scheduler-locking on, while there are other threads live.
On Linux, when the main thread exits without causing a whole-process
exit (e.g., via the main thread doing pthread_exit), the main thread
becomes zombie but does not report a thread exit event. When
eventually all other threads of the process exit, the main thread is
unblocked out of its zombie state and reports its exit which we
interpret as the whole-process exit.
If the main-thread-exit causes a whole-process exit (e.g., via the
exit syscall), the process is the same, except that the exit syscall
makes the kernel force-close all threads immediately.
Importantly, the main thread on Linux is always the last thread that
reports the exit event.
On Windows, the main thread exiting is not special at all. When the
main thread causes a process exit (e.g., for ExitProcess or by
returning from main), the debugger sees a normal thread exit event for
the main thread. All other threads will follow up with a thread-exit
event too, except whichever thread happens to be the last one. That
last one is the one that reports a whole-process-exit event instead of
an exit-thread event. So, since programs are typically multi-threaded
on Windows (because the OS/runtime spawns some threads), when the main
thread just returns from main(), it is very typically _not_ the main
thread that reports the whole-process exit.
As a result, stepping the main thread with schedlock on Windows
results in the main thread exiting and the continue aborting due to
no-resumed-threads left instead of a whole-process exit as seen on
Linux:
(gdb) info threads
Id Target Id Frame
* 1 Thread 11768.0x1bc "leader-exit-schedlock" main () at .../gdb.threads/leader-exit-schedlock.c:55
2 Thread 11768.0x31e0 (in kernel) 0x00007ffbb23dfc77 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
3 Thread 11768.0x2dec "sig" (in kernel) 0x00007ffbb23dc087 in ntdll!ZwReadFile () from C:/WINDOWS/SYSTEM32/ntdll.dll
4 Thread 11768.0x2530 (in kernel) 0x00007ffbb23dfc77 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
5 Thread 11768.0x3384 "leader-exit-schedlock" 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
6 Thread 11768.0x3198 "leader-exit-schedlock" 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
7 Thread 11768.0x1ab8 "leader-exit-schedlock" 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
8 Thread 11768.0x3fe4 "leader-exit-schedlock" 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
9 Thread 11768.0x3b5c "leader-exit-schedlock" 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
10 Thread 11768.0x45c "leader-exit-schedlock" 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
11 Thread 11768.0x3724 "leader-exit-schedlock" 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
12 Thread 11768.0x1e44 "leader-exit-schedlock" 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
13 Thread 11768.0x23f0 "leader-exit-schedlock" 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
14 Thread 11768.0x3b80 "leader-exit-schedlock" 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
(gdb) set scheduler-locking on
(gdb) c
Continuing.
[Thread 11768.0x1bc exited]
No unwaited-for children left.
(gdb) info threads
Id Target Id Frame
2 Thread 11768.0x31e0 (exiting) 0x00007ffbb23dfc77 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
3 Thread 11768.0x2dec "sig" (exiting) 0x00007ffbb23dc087 in ntdll!ZwReadFile () from C:/WINDOWS/SYSTEM32/ntdll.dll
4 Thread 11768.0x2530 (exiting) 0x00007ffbb23dfc77 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
5 Thread 11768.0x3384 "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
6 Thread 11768.0x3198 "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
7 Thread 11768.0x1ab8 "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
8 Thread 11768.0x3fe4 "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
9 Thread 11768.0x3b5c "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
10 Thread 11768.0x45c "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
11 Thread 11768.0x3724 "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
12 Thread 11768.0x1e44 "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
13 Thread 11768.0x23f0 "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
14 Thread 11768.0x3b80 "leader-exit-schedlock" (exiting process) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
The current thread <Thread ID 1> has terminated. See `help thread'.
(gdb)
The "(exiting)" and "(exiting process)" threads are threads for which
the kernel already reported their exit to GDB's Windows backend (via
WaitForDebugEvent), but the Windows backend hasn't yet reported the
event to infrun. The events are still pending in windows-nat.c.
The "(exiting process)" thread above (thread 14) is the one that won
the process-exit event lottery on the Windows kernel side (because it
was the last to exit). Continuing the (exiting) threads with
schedlock enabled should result in the Windows backend reporting that
thread's pending exit to infrun. While continuing thread 14 should
result in the inferior exiting. Vis:
(gdb) c
Continuing.
[Thread 11768.0x31e0 exited]
No unwaited-for children left.
(gdb) t 14
[Switching to thread 14 (Thread 11768.0x3b80)]
#0 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
(gdb) c
Continuing.
[Inferior 1 (process 11768) exited normally]
The testcase continues all the (exiting) threads, one by one, and then
finally continues the (exiting process) one, expecting an inferior
exit.
The testcase also tries a similar scenario: instead immediately
continue the (exiting process) thread without continuing the others.
That should result in the inferior exiting immediately.
It is actually not guaranteed that the Windows backend will consume
all the thread and process exit events out of the kernel before the
first thread exit event is processed by infrun. So often we will see
for example, instead:
(gdb) info threads
Id Target Id Frame
2 Thread 11768.0x31e0 (exiting) 0x00007ffbb23dfc77 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
3 Thread 11768.0x2dec "sig" (exiting) 0x00007ffbb23dc087 in ntdll!ZwReadFile () from C:/WINDOWS/SYSTEM32/ntdll.dll
4 Thread 11768.0x2530 (exiting) 0x00007ffbb23dfc77 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
5 Thread 11768.0x3384 "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
6 Thread 11768.0x3198 "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
7 Thread 11768.0x1ab8 "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
8 Thread 11768.0x3fe4 "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
9 Thread 11768.0x3b5c "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
10 Thread 11768.0x45c "leader-exit-schedlock" 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
11 Thread 11768.0x3724 "leader-exit-schedlock" 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
12 Thread 11768.0x1e44 "leader-exit-schedlock" 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
13 Thread 11768.0x23f0 "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
14 Thread 11768.0x3b80 "leader-exit-schedlock" (exiting) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
Above, we can't tell which thread will get the exit-process event,
there is no "(exiting process)" thread. We do know it'll be one of
threads 10, 11, and 12, because those do not have "(exiting)". The
Windows kernel has already decided which one it is at this point, we
just haven't seen the exit-process event yet.
This is actually what we _always_ see with "maint set target-non-stop
off" too, because in all-stop, the Windows backend only processes one
Windows debug event at a time.
So when the the test first continues all the (exiting) threads, one by
one, and then when there are no more "(exiting)" threads, if there is
no "(exiting process)" thread, it tries to exit the remaining threads,
(in the above case threads 10, 11 and 12), expecting that one of those
continues may cause an inferior exit.
On systems other than Windows, the testcase expects that continuing
the main thread results in an inferior exit. If we find out that
isn't correct for some system, we can adjust the testcase then.
Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: I52fb8de5e72bc12195ffb8bedd1d8070464332d3
commit-id:
5f751d8e