Skip to content

[lldb] Always compute the execution & symbol context #148994

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
8 changes: 8 additions & 0 deletions lldb/include/lldb/Core/Debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,15 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
return m_target_list.GetSelectedTarget();
}

/// Get the execution context for the selected target.
ExecutionContext GetSelectedExecutionContext();

struct SelectedContext {
ExecutionContext exe_ctx;
std::optional<SymbolContext> sym_ctx;
};
SelectedContext GetSelectedContext();

/// Get accessor for the target list.
///
/// The target list is part of the global debugger object. This the single
Expand Down
11 changes: 7 additions & 4 deletions lldb/include/lldb/Core/Statusline.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#ifndef LLDB_CORE_STATUSLINE_H
#define LLDB_CORE_STATUSLINE_H

#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/lldb-forward.h"
#include <cstdint>
#include <string>
Expand All @@ -25,9 +27,9 @@ class Statusline {
/// Hide the statusline and extend the scroll window.
void Disable();

/// Redraw the statusline. If update is false, this will redraw the last
/// string.
void Redraw(bool update = true);
/// Redraw the statusline. If both exe_ctx and sym_ctx are NULL, this redraws
/// the last string.
void Redraw(const ExecutionContext *exe_ctx, const SymbolContext *sym_ctx);

/// Inform the statusline that the terminal dimensions have changed.
void TerminalSizeChanged();
Expand All @@ -46,7 +48,8 @@ class Statusline {
void UpdateScrollWindow(ScrollWindowMode mode);

Debugger &m_debugger;
std::string m_last_str;
ExecutionContext m_exe_ctx;
SymbolContext m_symbol_ctx;
uint64_t m_terminal_width = 0;
uint64_t m_terminal_height = 0;
};
Expand Down
40 changes: 38 additions & 2 deletions lldb/source/Core/Debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1216,8 +1216,20 @@ void Debugger::RestoreInputTerminalState() {

void Debugger::RedrawStatusline(bool update) {
std::lock_guard<std::mutex> guard(m_statusline_mutex);

if (!update && m_statusline) {
m_statusline->Redraw(nullptr, nullptr);
return;
}

// Always compute the execution and symbol context, regardless of whether the
// statusline is enabled. This code gets called from the default event handler
// thread and has uncovered threading issues that otherwise only reproduce
// when the statusline is enabled.
SelectedContext ctx = GetSelectedContext();
if (m_statusline)
m_statusline->Redraw(update);
m_statusline->Redraw(&ctx.exe_ctx,
ctx.sym_ctx ? &ctx.sym_ctx.value() : nullptr);
}

ExecutionContext Debugger::GetSelectedExecutionContext() {
Expand All @@ -1226,6 +1238,27 @@ ExecutionContext Debugger::GetSelectedExecutionContext() {
return ExecutionContext(exe_ctx_ref);
}

Debugger::SelectedContext Debugger::GetSelectedContext() {
SelectedContext context;
context.exe_ctx = GetSelectedExecutionContext();

if (!context.exe_ctx.HasTargetScope())
context.exe_ctx.SetTargetPtr(&GetSelectedOrDummyTarget());

if (ProcessSP process_sp = context.exe_ctx.GetProcessSP()) {
// Check if the process is stopped, and if it is, make sure it remains
// stopped until we've computed the symbol context.
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process_sp->GetRunLock())) {
if (auto frame_sp = context.exe_ctx.GetFrameSP())
context.sym_ctx.emplace(
frame_sp->GetSymbolContext(eSymbolContextEverything));
}
}

return context;
}

void Debugger::DispatchInputInterrupt() {
std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
IOHandlerSP reader_sp(m_io_handler_stack.Top());
Expand Down Expand Up @@ -2117,13 +2150,16 @@ lldb::thread_result_t Debugger::DefaultEventHandler() {
while (!done) {
EventSP event_sp;
if (listener_sp->GetEvent(event_sp, std::nullopt)) {
bool update_statusline = false;
if (event_sp) {
Broadcaster *broadcaster = event_sp->GetBroadcaster();
if (broadcaster) {
uint32_t event_type = event_sp->GetType();
ConstString broadcaster_class(broadcaster->GetBroadcasterClass());
if (broadcaster_class == broadcaster_class_process) {
HandleProcessEvent(event_sp);
update_statusline =
(event_type & Process::eBroadcastBitStateChanged) != 0;
} else if (broadcaster_class == broadcaster_class_target) {
if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(
event_sp.get())) {
Expand Down Expand Up @@ -2168,7 +2204,7 @@ lldb::thread_result_t Debugger::DefaultEventHandler() {
if (m_forward_listener_sp)
m_forward_listener_sp->AddEvent(event_sp);
}
RedrawStatusline();
RedrawStatusline(update_statusline);
}
}

Expand Down
41 changes: 12 additions & 29 deletions lldb/source/Core/Statusline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,17 @@ void Statusline::TerminalSizeChanged() {

UpdateScrollWindow(ResizeStatusline);

// Draw the old statusline.
Redraw(/*update=*/false);
// Redraw the old statusline.
Redraw(nullptr, nullptr);
}

void Statusline::Enable() {
// Reduce the scroll window to make space for the status bar below.
UpdateScrollWindow(EnableStatusline);

// Draw the statusline.
Redraw(/*update=*/true);
Debugger::SelectedContext ctx = m_debugger.GetSelectedContext();
Redraw(&ctx.exe_ctx, ctx.sym_ctx ? &ctx.sym_ctx.value() : nullptr);
}

void Statusline::Disable() {
Expand All @@ -69,8 +70,6 @@ void Statusline::Draw(std::string str) {
if (!stream_sp)
return;

m_last_str = str;

str = ansi::TrimAndPad(str, m_terminal_width);

LockedStreamFile locked_stream = stream_sp->Lock();
Expand Down Expand Up @@ -127,34 +126,18 @@ void Statusline::UpdateScrollWindow(ScrollWindowMode mode) {
m_debugger.RefreshIOHandler();
}

void Statusline::Redraw(bool update) {
if (!update) {
Draw(m_last_str);
return;
}
void Statusline::Redraw(const ExecutionContext *exe_ctx,
const SymbolContext *sym_ctx) {
if (exe_ctx)
m_exe_ctx = *exe_ctx;

ExecutionContext exe_ctx = m_debugger.GetSelectedExecutionContext();

// For colors and progress events, the format entity needs access to the
// debugger, which requires a target in the execution context.
if (!exe_ctx.HasTargetScope())
exe_ctx.SetTargetPtr(&m_debugger.GetSelectedOrDummyTarget());

SymbolContext symbol_ctx;
if (ProcessSP process_sp = exe_ctx.GetProcessSP()) {
// Check if the process is stopped, and if it is, make sure it remains
// stopped until we've computed the symbol context.
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process_sp->GetRunLock())) {
if (auto frame_sp = exe_ctx.GetFrameSP())
symbol_ctx = frame_sp->GetSymbolContext(eSymbolContextEverything);
}
}
if (sym_ctx)
m_symbol_ctx = *sym_ctx;

StreamString stream;
FormatEntity::Entry format = m_debugger.GetStatuslineFormat();
FormatEntity::Format(format, stream, &symbol_ctx, &exe_ctx, nullptr, nullptr,
false, false);
FormatEntity::Format(format, stream, &m_symbol_ctx, &m_exe_ctx, nullptr,
nullptr, false, false);

Draw(stream.GetString().str());
}
Loading