Skip to content

[lldb] Guard SBFrame/SBThread methods against running processes #152020

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lldb/include/lldb/API/SBFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ class LLDB_API SBFrame {

void SetFrameSP(const lldb::StackFrameSP &lldb_object_sp);

/// Return an SBValue containing an error message that warns the process is
/// not currently stopped.
static SBValue CreateProcessIsRunningExprEvalError();

lldb::ExecutionContextRefSP m_opaque_sp;
};

Expand Down
5 changes: 5 additions & 0 deletions lldb/include/lldb/Host/ProcessRunLock.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@ class ProcessRunLock {
class ProcessRunLocker {
public:
ProcessRunLocker() = default;
ProcessRunLocker(ProcessRunLocker &&other) : m_lock(other.m_lock) {
other.m_lock = nullptr;
}

~ProcessRunLocker() { Unlock(); }

bool IsLocked() const { return m_lock; }

// Try to lock the read lock, but only do so if there are no writers.
bool TryLock(ProcessRunLock *lock) {
if (m_lock) {
Expand Down
22 changes: 17 additions & 5 deletions lldb/include/lldb/Target/ExecutionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <mutex>

#include "lldb/Host/ProcessRunLock.h"
#include "lldb/Target/StackID.h"
#include "lldb/lldb-private.h"

Expand Down Expand Up @@ -315,14 +316,25 @@ class ExecutionContext {
ExecutionContext(const ExecutionContextRef *exe_ctx_ref,
bool thread_and_frame_only_if_stopped = false);

// These two variants take in a locker, and grab the target, lock the API
// mutex into locker, then fill in the rest of the shared pointers.
/// These two variants take in an API lock and a process run lock.
/// If the ExecutionContextRef has a Target, the API lock will be acquired.
/// If the ExecutionContextRef also has a Process, an attempt to acquire
/// ProcessRunLock is made. If successful (i.e. the Process is stopped), frame
/// and thread information might be available.
/// As a corollary, if the ProcessRunLocker has been locked, this
/// ExecutionContext contains non-null Process and Target pointers.
/// If a Status object is provided, it will be updated if the
/// ExecutionContextRef/Process/Target are null, or if the process is running.
ExecutionContext(const ExecutionContextRef &exe_ctx_ref,
std::unique_lock<std::recursive_mutex> &locker)
: ExecutionContext(&exe_ctx_ref, locker) {}
std::unique_lock<std::recursive_mutex> &api_lock,
ProcessRunLock::ProcessRunLocker &stop_locker,
Status *status = nullptr)
: ExecutionContext(&exe_ctx_ref, api_lock, stop_locker, status) {}

ExecutionContext(const ExecutionContextRef *exe_ctx_ref,
std::unique_lock<std::recursive_mutex> &locker);
std::unique_lock<std::recursive_mutex> &api_lock,
ProcessRunLock::ProcessRunLocker &stop_locker,
Status *status = nullptr);
// Create execution contexts from execution context scopes
ExecutionContext(ExecutionContextScope *exe_scope);
ExecutionContext(ExecutionContextScope &exe_scope);
Expand Down
Loading
Loading