LLDB mainline
Statusline.cpp
Go to the documentation of this file.
1//===-- Statusline.cpp ---------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "lldb/Core/Debugger.h"
15#include "lldb/Target/Process.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/Support/Locale.h"
21
22#define ESCAPE "\x1b"
23#define ANSI_NORMAL ESCAPE "[0m"
24#define ANSI_SAVE_CURSOR ESCAPE "7"
25#define ANSI_RESTORE_CURSOR ESCAPE "8"
26#define ANSI_CLEAR_BELOW ESCAPE "[J"
27#define ANSI_CLEAR_SCREEN ESCAPE "[2J"
28#define ANSI_SET_SCROLL_ROWS ESCAPE "[1;%ur"
29#define ANSI_TO_START_OF_ROW ESCAPE "[%u;1f"
30#define ANSI_REVERSE_VIDEO ESCAPE "[7m"
31#define ANSI_UP_ROWS ESCAPE "[%dA"
32
33using namespace lldb;
34using namespace lldb_private;
35
37 : m_debugger(debugger), m_terminal_width(m_debugger.GetTerminalWidth()),
38 m_terminal_height(m_debugger.GetTerminalHeight()) {}
39
41
43 m_terminal_width = m_debugger.GetTerminalWidth();
44 m_terminal_height = m_debugger.GetTerminalHeight();
45
47
48 // Redraw the old statusline.
49 Redraw(std::nullopt);
50}
51
52void Statusline::Enable(std::optional<ExecutionContextRef> exe_ctx_ref) {
53 // Reduce the scroll window to make space for the status bar below.
55
56 // Draw the statusline.
57 Redraw(exe_ctx_ref);
58}
59
61 // Extend the scroll window to cover the status bar.
63}
64
65void Statusline::Draw(std::string str) {
66 lldb::LockableStreamFileSP stream_sp = m_debugger.GetOutputStreamSP();
67 if (!stream_sp)
68 return;
69
71
72 LockedStreamFile locked_stream = stream_sp->Lock();
73 locked_stream << ANSI_SAVE_CURSOR;
74 locked_stream.Printf(ANSI_TO_START_OF_ROW,
75 static_cast<unsigned>(m_terminal_height));
76
77 // Use "reverse video" to make sure the statusline has a background. Only do
78 // this when colors are disabled, and rely on the statusline format otherwise.
79 if (!m_debugger.GetUseColor())
80 locked_stream << ANSI_REVERSE_VIDEO;
81
82 locked_stream << str;
83 locked_stream << ANSI_NORMAL;
84 locked_stream << ANSI_RESTORE_CURSOR;
85}
86
88 assert(m_terminal_width != 0 && m_terminal_height != 0);
89
90 lldb::LockableStreamFileSP stream_sp = m_debugger.GetOutputStreamSP();
91 if (!stream_sp)
92 return;
93
94 const unsigned reduced_scroll_window = m_terminal_height - 1;
95 LockedStreamFile locked_stream = stream_sp->Lock();
96
97 switch (mode) {
99 // Move everything on the screen up.
100 locked_stream << '\n';
101 locked_stream.Printf(ANSI_UP_ROWS, 1);
102 // Reduce the scroll window.
103 locked_stream << ANSI_SAVE_CURSOR;
104 locked_stream.Printf(ANSI_SET_SCROLL_ROWS, reduced_scroll_window);
105 locked_stream << ANSI_RESTORE_CURSOR;
106 break;
108 // Reset the scroll window.
109 locked_stream << ANSI_SAVE_CURSOR;
110 locked_stream.Printf(ANSI_SET_SCROLL_ROWS, 0);
111 locked_stream << ANSI_RESTORE_CURSOR;
112 // Clear the screen below to hide the old statusline.
113 locked_stream << ANSI_CLEAR_BELOW;
114 break;
115 case ResizeStatusline:
116 // Clear the screen and update the scroll window.
117 // FIXME: Find a better solution (#146919).
118 locked_stream << ANSI_CLEAR_SCREEN;
119 locked_stream.Printf(ANSI_SET_SCROLL_ROWS, reduced_scroll_window);
120 break;
121 }
122
123 m_debugger.RefreshIOHandler();
124}
125
126void Statusline::Redraw(std::optional<ExecutionContextRef> exe_ctx_ref) {
127 // Update the cached execution context.
128 if (exe_ctx_ref)
129 m_exe_ctx_ref = *exe_ctx_ref;
130
131 // Lock the execution context.
132 ExecutionContext exe_ctx =
133 m_exe_ctx_ref.Lock(/*thread_and_frame_only_if_stopped=*/false);
134
135 // Compute the symbol context if we're stopped.
136 SymbolContext sym_ctx;
137 llvm::Expected<StoppedExecutionContext> stopped_exe_ctx =
139 if (stopped_exe_ctx) {
140 // The StoppedExecutionContext only ensures that we hold the run lock.
141 // The process could be in an exited or unloaded state and have no frame.
142 if (auto frame_sp = stopped_exe_ctx->GetFrameSP())
143 sym_ctx = frame_sp->GetSymbolContext(eSymbolContextEverything);
144 } else {
145 // We can draw the statusline without being stopped.
146 llvm::consumeError(stopped_exe_ctx.takeError());
147 }
148
149 StreamString stream;
150 FormatEntity::Entry format = m_debugger.GetStatuslineFormat();
151 FormatEntity::Format(format, stream, &sym_ctx, &exe_ctx, nullptr, nullptr,
152 false, false);
153
154 Draw(stream.GetString().str());
155}
#define ANSI_SET_SCROLL_ROWS
#define ANSI_TO_START_OF_ROW
#define ANSI_CLEAR_SCREEN
#define ANSI_UP_ROWS
#define ANSI_SAVE_CURSOR
#define ANSI_NORMAL
#define ANSI_RESTORE_CURSOR
#define ANSI_REVERSE_VIDEO
#define ANSI_CLEAR_BELOW
A class to manage flag bits.
Definition Debugger.h:80
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void UpdateScrollWindow(ScrollWindowMode mode)
Set the scroll window for the given mode.
void TerminalSizeChanged()
Inform the statusline that the terminal dimensions have changed.
void Enable(std::optional< ExecutionContextRef > exe_ctx_ref)
Reduce the scroll window and draw the statusline.
Statusline(Debugger &debugger)
void Redraw(std::optional< ExecutionContextRef > exe_ctx_ref)
Redraw the statusline.
void Disable()
Hide the statusline and extend the scroll window.
ExecutionContextRef m_exe_ctx_ref
Cached copy of the execution context that allows us to redraw the statusline.
Definition Statusline.h:55
void Draw(std::string msg)
Draw the statusline with the given text.
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
Defines a symbol context baton that can be handed other debug core functions.
bool Format(const Entry &entry, Stream &s, const SymbolContext *sc, const ExecutionContext *exe_ctx, const Address *addr, ValueObject *valobj, bool function_changed, bool initial_function)
std::string TrimAndPad(llvm::StringRef str, size_t visible_length, char padding=' ')
A class that represents a running process on the host machine.
llvm::Expected< StoppedExecutionContext > GetStoppedExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr)
std::shared_ptr< lldb_private::LockableStreamFile > LockableStreamFileSP