clang 20.0.0 (based on r547379) from build 12806354. Bug: http://b/379133546 Test: N/A Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
162 lines
4.8 KiB
C++
162 lines
4.8 KiB
C++
//===-- ThreadList.h --------------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLDB_TARGET_THREADLIST_H
|
|
#define LLDB_TARGET_THREADLIST_H
|
|
|
|
#include <mutex>
|
|
#include <vector>
|
|
|
|
#include "lldb/Target/Thread.h"
|
|
#include "lldb/Target/ThreadCollection.h"
|
|
#include "lldb/Utility/Iterable.h"
|
|
#include "lldb/Utility/UserID.h"
|
|
#include "lldb/lldb-private.h"
|
|
|
|
namespace lldb_private {
|
|
|
|
// This is a thread list with lots of functionality for use only by the process
|
|
// for which this is the thread list. A generic container class with iterator
|
|
// functionality is ThreadCollection.
|
|
class ThreadList : public ThreadCollection {
|
|
friend class Process;
|
|
|
|
public:
|
|
ThreadList(Process &process);
|
|
|
|
ThreadList(const ThreadList &rhs);
|
|
|
|
~ThreadList() override;
|
|
|
|
/// Precondition: both thread lists must be belong to the same process.
|
|
const ThreadList &operator=(const ThreadList &rhs);
|
|
|
|
uint32_t GetSize(bool can_update = true);
|
|
|
|
// Return the selected thread if there is one. Otherwise, return the thread
|
|
// selected at index 0.
|
|
lldb::ThreadSP GetSelectedThread();
|
|
|
|
// Manage the thread to use for running expressions. This is usually the
|
|
// Selected thread, but sometimes (e.g. when evaluating breakpoint conditions
|
|
// & stop hooks) it isn't.
|
|
class ExpressionExecutionThreadPusher {
|
|
public:
|
|
ExpressionExecutionThreadPusher(ThreadList &thread_list, lldb::tid_t tid)
|
|
: m_thread_list(&thread_list), m_tid(tid) {
|
|
m_thread_list->PushExpressionExecutionThread(m_tid);
|
|
}
|
|
|
|
ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp);
|
|
|
|
~ExpressionExecutionThreadPusher() {
|
|
if (m_thread_list && m_tid != LLDB_INVALID_THREAD_ID)
|
|
m_thread_list->PopExpressionExecutionThread(m_tid);
|
|
}
|
|
|
|
private:
|
|
ThreadList *m_thread_list;
|
|
lldb::tid_t m_tid;
|
|
};
|
|
|
|
lldb::ThreadSP GetExpressionExecutionThread();
|
|
|
|
protected:
|
|
void PushExpressionExecutionThread(lldb::tid_t tid);
|
|
|
|
void PopExpressionExecutionThread(lldb::tid_t tid);
|
|
|
|
public:
|
|
bool SetSelectedThreadByID(lldb::tid_t tid, bool notify = false);
|
|
|
|
bool SetSelectedThreadByIndexID(uint32_t index_id, bool notify = false);
|
|
|
|
void Clear();
|
|
|
|
void Flush();
|
|
|
|
void Destroy();
|
|
|
|
// Note that "idx" is not the same as the "thread_index". It is a zero based
|
|
// index to accessing the current threads, whereas "thread_index" is a unique
|
|
// index assigned
|
|
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update = true);
|
|
|
|
lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update = true);
|
|
|
|
lldb::ThreadSP FindThreadByProtocolID(lldb::tid_t tid,
|
|
bool can_update = true);
|
|
|
|
lldb::ThreadSP RemoveThreadByID(lldb::tid_t tid, bool can_update = true);
|
|
|
|
lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid,
|
|
bool can_update = true);
|
|
|
|
lldb::ThreadSP FindThreadByIndexID(uint32_t index_id, bool can_update = true);
|
|
|
|
lldb::ThreadSP GetThreadSPForThreadPtr(Thread *thread_ptr);
|
|
|
|
lldb::ThreadSP GetBackingThread(const lldb::ThreadSP &real_thread);
|
|
|
|
bool ShouldStop(Event *event_ptr);
|
|
|
|
Vote ShouldReportStop(Event *event_ptr);
|
|
|
|
Vote ShouldReportRun(Event *event_ptr);
|
|
|
|
void RefreshStateAfterStop();
|
|
|
|
/// The thread list asks tells all the threads it is about to resume.
|
|
/// If a thread can "resume" without having to resume the target, it
|
|
/// will return false for WillResume, and then the process will not be
|
|
/// restarted.
|
|
///
|
|
/// \return
|
|
/// \b true instructs the process to resume normally,
|
|
/// \b false means start & stopped events will be generated, but
|
|
/// the process will not actually run. The thread must then return
|
|
/// the correct StopInfo when asked.
|
|
///
|
|
bool WillResume();
|
|
|
|
void DidResume();
|
|
|
|
void DidStop();
|
|
|
|
void DiscardThreadPlans();
|
|
|
|
uint32_t GetStopID() const;
|
|
|
|
void SetStopID(uint32_t stop_id);
|
|
|
|
std::recursive_mutex &GetMutex() const override;
|
|
|
|
/// Precondition: both thread lists must be belong to the same process.
|
|
void Update(ThreadList &rhs);
|
|
|
|
protected:
|
|
void SetShouldReportStop(Vote vote);
|
|
|
|
void NotifySelectedThreadChanged(lldb::tid_t tid);
|
|
|
|
// Classes that inherit from Process can see and modify these
|
|
Process &m_process; ///< The process that manages this thread list.
|
|
uint32_t
|
|
m_stop_id; ///< The process stop ID that this thread list is valid for.
|
|
lldb::tid_t
|
|
m_selected_tid; ///< For targets that need the notion of a current thread.
|
|
std::vector<lldb::tid_t> m_expression_tid_stack;
|
|
|
|
private:
|
|
ThreadList() = delete;
|
|
};
|
|
|
|
} // namespace lldb_private
|
|
|
|
#endif // LLDB_TARGET_THREADLIST_H
|