Skip to content

Commit cd4630d

Browse files
committed
[lldb] Implement statusline
Add a statusline to command-line LLDB to display progress events and other information related to the current state of the debugger. The statusline is a dedicated area displayed the bottom of the screen. The contents of the status line are configurable through a setting consisting of LLDB’s format strings. The statusline is configurable through the `statusline-format` setting. The default configuration shows the target name, the current file, the stop reason and the current progress event. ``` (lldb) settings show statusline-format statusline-format (format-string) = "${ansi.bg.cyan}${ansi.fg.black}{${target.file.basename}}{ | ${line.file.basename}:${line.number}:${line.column}}{ | ${thread.stop-reason}}{ | {${progress.count} }${progress.message}}" ``` The statusline is enabled by default, but can be disabled with the following setting: ``` (lldb) settings set show-statusline false ``` The statusline supersedes the current progress reporting implementation. Consequently, the following settings no longer have any effect (but continue to exist): ``` show-progress -- Whether to show progress or not if the debugger's output is an interactive color-enabled terminal. show-progress-ansi-prefix -- When displaying progress in a color-enabled terminal, use the ANSI terminal code specified in this format immediately before the progress message. show-progress-ansi-suffix -- When displaying progress in a color-enabled terminal, use the ANSI terminal code specified in this format immediately after the progress message. ``` RFC: https://discourse.llvm.org/t/rfc-lldb-statusline/83948
1 parent fbea21a commit cd4630d

File tree

10 files changed

+406
-85
lines changed

10 files changed

+406
-85
lines changed

lldb/include/lldb/Core/Debugger.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "lldb/Core/FormatEntity.h"
2020
#include "lldb/Core/IOHandler.h"
2121
#include "lldb/Core/SourceManager.h"
22+
#include "lldb/Core/Statusline.h"
2223
#include "lldb/Core/UserSettingsController.h"
2324
#include "lldb/Host/HostThread.h"
2425
#include "lldb/Host/StreamFile.h"
@@ -308,6 +309,10 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
308309

309310
bool SetShowProgress(bool show_progress);
310311

312+
bool GetShowStatusline() const;
313+
314+
const FormatEntity::Entry *GetStatuslineFormat() const;
315+
311316
llvm::StringRef GetShowProgressAnsiPrefix() const;
312317

313318
llvm::StringRef GetShowProgressAnsiSuffix() const;
@@ -604,6 +609,14 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
604609
return m_source_file_cache;
605610
}
606611

612+
struct ProgressReport {
613+
uint64_t id;
614+
uint64_t completed;
615+
uint64_t total;
616+
std::string message;
617+
};
618+
std::optional<ProgressReport> GetCurrentProgressReport() const;
619+
607620
protected:
608621
friend class CommandInterpreter;
609622
friend class REPL;
@@ -728,7 +741,7 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
728741
IOHandlerStack m_io_handler_stack;
729742
std::recursive_mutex m_io_handler_synchronous_mutex;
730743

731-
std::optional<uint64_t> m_current_event_id;
744+
std::optional<Statusline> m_statusline;
732745

733746
llvm::StringMap<std::weak_ptr<LogHandler>> m_stream_handlers;
734747
std::shared_ptr<CallbackLogHandler> m_callback_handler_sp;
@@ -745,6 +758,12 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
745758
lldb::TargetSP m_dummy_target_sp;
746759
Diagnostics::CallbackID m_diagnostics_callback_id;
747760

761+
/// Bookkeeping for command line progress events.
762+
/// @{
763+
llvm::SmallVector<ProgressReport, 4> m_progress_reports;
764+
mutable std::mutex m_progress_reports_mutex;
765+
/// @}
766+
748767
std::mutex m_destroy_callback_mutex;
749768
lldb::callback_token_t m_destroy_callback_next_token = 0;
750769
struct DestroyCallbackInfo {

lldb/include/lldb/Core/FormatEntity.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ struct Entry {
6767
ScriptThread,
6868
ThreadInfo,
6969
TargetArch,
70+
TargetFile,
7071
ScriptTarget,
7172
ModuleFile,
7273
File,
@@ -99,7 +100,9 @@ struct Entry {
99100
LineEntryColumn,
100101
LineEntryStartAddress,
101102
LineEntryEndAddress,
102-
CurrentPCArrow
103+
CurrentPCArrow,
104+
ProgressCount,
105+
ProgressMessage,
103106
};
104107

105108
struct Definition {

lldb/include/lldb/Core/Statusline.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===-- Statusline.h -----------------------------------------------------===//
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+
#include "lldb/Core/Debugger.h"
9+
#include "llvm/ADT/SmallVector.h"
10+
#include <string>
11+
#ifndef LLDB_CORE_STATUSBAR_H
12+
#define LLDB_CORE_STATUSBAR_H
13+
14+
namespace lldb_private {
15+
class Statusline {
16+
public:
17+
Statusline(Debugger &debugger);
18+
~Statusline();
19+
20+
void Enable();
21+
void Disable();
22+
23+
void Clear();
24+
void Update();
25+
26+
void TerminalSizeChanged() { m_terminal_size_has_changed = 1; }
27+
28+
private:
29+
// Draw the statusline with the given text.
30+
void Draw(llvm::StringRef msg);
31+
32+
// Update terminal dimensions.
33+
void UpdateTerminalProperties();
34+
35+
// Set the scroll window to the given height.
36+
void SetScrollWindow(uint64_t height);
37+
38+
// Write at the given column.
39+
void AddAtPosition(uint64_t col, llvm::StringRef str);
40+
41+
// Clear the statusline (without redrawing the background).
42+
void Reset();
43+
44+
bool IsSupported() const;
45+
46+
lldb::thread_result_t StatuslineThread();
47+
48+
Debugger &m_debugger;
49+
50+
volatile std::sig_atomic_t m_terminal_size_has_changed = 1;
51+
uint64_t m_terminal_width = 0;
52+
uint64_t m_terminal_height = 0;
53+
uint64_t m_scroll_height = 0;
54+
55+
static constexpr llvm::StringLiteral k_ansi_suffix = "${ansi.normal}";
56+
};
57+
} // namespace lldb_private
58+
#endif // LLDB_CORE_STATUSBAR_H

lldb/include/lldb/Utility/AnsiTerminal.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
#include "llvm/ADT/ArrayRef.h"
7474
#include "llvm/ADT/STLExtras.h"
7575
#include "llvm/ADT/StringRef.h"
76+
#include "llvm/Support/Regex.h"
7677

7778
#include <string>
7879

@@ -172,6 +173,32 @@ inline std::string FormatAnsiTerminalCodes(llvm::StringRef format,
172173
return fmt;
173174
}
174175
}
176+
177+
inline std::string StripAnsiTerminalCodes(llvm::StringRef str) {
178+
std::string stripped;
179+
while (!str.empty()) {
180+
llvm::StringRef left, right;
181+
182+
std::tie(left, right) = str.split(ANSI_ESC_START);
183+
stripped += left;
184+
185+
// ANSI_ESC_START not found.
186+
if (right.empty())
187+
break;
188+
189+
std::tie(left, right) = right.split(ANSI_ESC_END);
190+
191+
// ANSI_ESC_END not found.
192+
if (right.empty()) {
193+
stripped += ANSI_ESC_START;
194+
stripped += left;
195+
}
196+
197+
str = right;
198+
}
199+
return stripped;
200+
}
201+
175202
} // namespace lldb_private
176203

177204
#endif

lldb/source/Core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ add_lldb_library(lldbCore
4646
Opcode.cpp
4747
PluginManager.cpp
4848
Progress.cpp
49+
Statusline.cpp
4950
RichManglingContext.cpp
5051
SearchFilter.cpp
5152
Section.cpp

lldb/source/Core/CoreProperties.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@ let Definition = "debugger" in {
172172
Global,
173173
DefaultStringValue<"${ansi.normal}">,
174174
Desc<"When displaying progress in a color-enabled terminal, use the ANSI terminal code specified in this format immediately after the progress message.">;
175+
def ShowStatusline: Property<"show-statusline", "Boolean">,
176+
Global,
177+
DefaultTrue,
178+
Desc<"Whether to show a statusline at the bottom of the terminal.">;
179+
def StatuslineFormat: Property<"statusline-format", "FormatEntity">,
180+
Global,
181+
DefaultStringValue<"${ansi.bg.blue}${ansi.fg.black}{${target.file.basename}}{ | ${line.file.basename}:${line.number}:${line.column}}{ | ${thread.stop-reason}}{ | {${progress.count} }${progress.message}}">,
182+
Desc<"List of statusline format entities.">;
175183
def UseSourceCache: Property<"use-source-cache", "Boolean">,
176184
Global,
177185
DefaultTrue,

0 commit comments

Comments
 (0)