A problem is that a thread might not execute unless you call WaitFor before Terminate is called. The reason is that the internal function ThreadProc does not start Execute if the thread is already terminated.

The ThreadProc in the System.Classes unit is an ideal place to set breakpoints in order to see which threads might start.

Other useful places to set breakpoints:

TAnonymousThread.Execute

TExternalThread.Execute

Execute not being called by ThreadProc is a bug, but it is not documented because QC is gone (taking the below entry with it), it is not in QP and the docwiki never got updated.

Given QC has so much information, I am still baffled that Embarcadero took it down.

Note that application shutdown is a much debated topic. Best is to do as little cleanup as possible: your process is going to terminate soon anyway. No need to close handles or free memory: Windows will do that for you anyway. See for instance: