[lldb] Fix circular dependency and deadlock in scripted frame providers (#187411)
When a scripted frame provider calls back into the thread's frame
machinery (e.g. via HandleCommand or EvaluateExpression), two problems
arise:
1. GetStackFrameList() re-enters the SyntheticStackFrameList
construction, causing infinite recursion.
2. ClearStackFrames() tries to read-lock the StackFrameList's
shared_mutex that is already write-locked by GetFramesUpTo,
causing a deadlock.
This patch fixes those issues by tracking when a provider is actively
fetching frames via a per-host-thread map (m_provider_frames_by_thread)
keyed by HostThread. The map is pushed/popped in
SyntheticStackFrameList::FetchFramesUpTo before calling into the
provider. GetStackFrameList() checks it to route re-entrant calls:
- The provider's own host thread gets the parent frame list, preventing
circular dependency when get_frame_at_index calls back into
GetFrameAtIndex.
- The private state thread also gets the parent frame list, preventing
deadlock when a provider calls EvaluateExpression (which needs the
private state thread to process events).
- Other host threads proceed normally and block on the frame list mutex
until the provider finishes, getting the correct synthetic result.
ClearStackFrames() returns early if any provider is active, since the
frame state is shared and tearing it down while a provider is
mid-construction is both unnecessary and unsafe.
rdar://171558394
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>