Skip to content

Commit 1352444

Browse files
committed
[lldb] Implement a statusline in LLDB
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 0ba391a commit 1352444

File tree

13 files changed

+458
-135
lines changed

13 files changed

+458
-135
lines changed

lldb/include/lldb/Core/Debugger.h

Lines changed: 23 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"
@@ -303,6 +304,10 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
303304

304305
bool SetShowProgress(bool show_progress);
305306

307+
bool GetShowStatusline() const;
308+
309+
const FormatEntity::Entry *GetStatuslineFormat() const;
310+
306311
llvm::StringRef GetShowProgressAnsiPrefix() const;
307312

308313
llvm::StringRef GetShowProgressAnsiSuffix() const;
@@ -599,11 +604,20 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
599604
return m_source_file_cache;
600605
}
601606

607+
struct ProgressReport {
608+
uint64_t id;
609+
uint64_t completed;
610+
uint64_t total;
611+
std::string message;
612+
};
613+
std::optional<ProgressReport> GetCurrentProgressReport() const;
614+
602615
protected:
603616
friend class CommandInterpreter;
604617
friend class REPL;
605618
friend class Progress;
606619
friend class ProgressManager;
620+
friend class Statusline;
607621

608622
/// Report progress events.
609623
///
@@ -656,6 +670,8 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
656670
lldb::LockableStreamFileSP GetErrorStreamSP() { return m_error_stream_sp; }
657671
/// @}
658672

673+
bool StatuslineSupported();
674+
659675
void PushIOHandler(const lldb::IOHandlerSP &reader_sp,
660676
bool cancel_top_handler = true);
661677

@@ -732,7 +748,7 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
732748
IOHandlerStack m_io_handler_stack;
733749
std::recursive_mutex m_io_handler_synchronous_mutex;
734750

735-
std::optional<uint64_t> m_current_event_id;
751+
std::optional<Statusline> m_statusline;
736752

737753
llvm::StringMap<std::weak_ptr<LogHandler>> m_stream_handlers;
738754
std::shared_ptr<CallbackLogHandler> m_callback_handler_sp;
@@ -749,6 +765,12 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
749765
lldb::TargetSP m_dummy_target_sp;
750766
Diagnostics::CallbackID m_diagnostics_callback_id;
751767

768+
/// Bookkeeping for command line progress events.
769+
/// @{
770+
llvm::SmallVector<ProgressReport, 4> m_progress_reports;
771+
mutable std::mutex m_progress_reports_mutex;
772+
/// @}
773+
752774
std::mutex m_destroy_callback_mutex;
753775
lldb::callback_token_t m_destroy_callback_next_token = 0;
754776
struct DestroyCallbackInfo {

lldb/include/lldb/Core/FormatEntity.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ struct Entry {
100100
LineEntryColumn,
101101
LineEntryStartAddress,
102102
LineEntryEndAddress,
103-
CurrentPCArrow
103+
CurrentPCArrow,
104+
ProgressCount,
105+
ProgressMessage,
104106
};
105107

106108
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+
9+
#ifndef LLDB_CORE_STATUSLINE_H
10+
#define LLDB_CORE_STATUSLINE_H
11+
12+
#include "lldb/lldb-forward.h"
13+
#include "llvm/ADT/StringRef.h"
14+
#include <csignal>
15+
#include <string>
16+
17+
namespace lldb_private {
18+
class Statusline {
19+
public:
20+
Statusline(Debugger &debugger);
21+
~Statusline();
22+
23+
/// Reduce the scroll window and draw the statusline.
24+
void Enable();
25+
26+
/// Hide the statusline and extend the scroll window.
27+
void Disable();
28+
29+
/// Redraw the statusline. If update is false, this will redraw the last
30+
/// string.
31+
void Redraw(bool update = true);
32+
33+
/// Inform the statusline that the terminal dimensions have changed.
34+
void TerminalSizeChanged();
35+
36+
private:
37+
/// Draw the statusline with the given text.
38+
void Draw(std::string msg);
39+
40+
/// Update terminal dimensions.
41+
void UpdateTerminalProperties();
42+
43+
/// Set the scroll window to the given height.
44+
void SetScrollWindow(uint64_t height);
45+
46+
/// Clear the statusline (without redrawing the background).
47+
void Reset();
48+
49+
Debugger &m_debugger;
50+
std::string m_last_str;
51+
52+
volatile std::sig_atomic_t m_terminal_size_has_changed = 1;
53+
uint64_t m_terminal_width = 0;
54+
uint64_t m_terminal_height = 0;
55+
uint64_t m_scroll_height = 0;
56+
};
57+
} // namespace lldb_private
58+
#endif // LLDB_CORE_STATUSLINE_H

lldb/packages/Python/lldbsuite/test/lldbtest.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,8 @@ def setUpCommands(cls):
765765
# Disable fix-its by default so that incorrect expressions in tests don't
766766
# pass just because Clang thinks it has a fix-it.
767767
"settings set target.auto-apply-fixits false",
768+
# Disable the statusline in PExpect tests.
769+
"settings set show-statusline false",
768770
# Testsuite runs in parallel and the host can have also other load.
769771
"settings set plugin.process.gdb-remote.packet-timeout 60",
770772
'settings set symbols.clang-modules-cache-path "{}"'.format(

lldb/source/Core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ add_lldb_library(lldbCore
5050
Opcode.cpp
5151
PluginManager.cpp
5252
Progress.cpp
53+
Statusline.cpp
5354
RichManglingContext.cpp
5455
SearchFilter.cpp
5556
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)