How do I know that a Thread has exited?

I had asked in Stackoverflow about how to detect if a program Thread has exited using the LLDB Python API

The answer given was that the thread object is valid (while thread is True) until it exists. However in practice, it doesn’t seem to be the case and the following loop continues forever, even after my Thread has executed all the code

    process = target.Launch(l, error)
    thread = process.GetThreadAtIndex(0)

    while thread:
        thread.StepOver()
        frame = thread.get_thread_frames()[-1]
        if not start_fp or start_fp != frame:
            print("%s::"%(frame,))
            start_fp = frame
    return

Is a property or a method on lldb.SBThread that I can check to see if the Thread has exited ?
If not is thread.num_frames == 0 a valid way of detecting that a thread no longer is executing any code ?

In our test files we generally look at process’ state, for example: llvm-project/lldb/test/API/android/platform/TestDefaultCacheLineSize.py at main · llvm/llvm-project · GitHub

SBThread has a GetState(), which likely acts the same way. Something like while thread.GetStatus() != lldb......

I can’t say for sure what bool(thread) is calling but I would guess it is SBThread::IsValid and I could understand a stopped thread still being a valid object. Otherwise you wouldn’t be able to ask it if it was stopped.

And if you want to find all the possible calls you can look at LLDB python API. It’s not super fancy but if you add “SB” before the thing you want you’ll find the scripting class for it. SBThread in this case.

I used process.GetState() != lldb.eStateExited as well and it works.
I wanted to use lldb to suspend, resume and breakpoint on individual threads, to see if I can simulate some mult-threaded programs and locks etc, which is why I wanted to know if there are thread level reasons I can look at.

Close thing I found was checking the thread.GetStopReason()'s return value. A value of 9, 0, 1 (ThreadExiting, Invalid or None) seems to be the sign that a Thread has exited.
After the last instruction is executed, GetStopReason() returns 1(lldb.eStopReasonNone).

So it looks the only way to know if a Thread exited normally is to check if the GetStopReason() == 1

Currently, the foolproof way to know whether a thread has exited or not is if

SBProcess.GetThreadByID(my_thread.GetThreadID())

returns anything. lldb doesn’t require systems to support “thread exit notification” so the only way lldb knows that a thread is gone is that at some stop lldb looked up the TID in the list of threads reported by the debug stub and it wasn’t there, so you are also asking the question lldb asks…

However, it’s not a bad idea to mark exited threads as exited at the point where lldb merges old & new thread lists and finds a thread missing. IIRC that gets managed in the individual process plugins so you might have to do it separately for gdb-remote & Windows. But that shouldn’t be a hard patch to write up. And using eStateExited seems fine.