[Lldb-commits] [lldb] 9aef315 - [lldb] Add SBDebugger::SetTerminalDimensions to set width and height atomically (#201965)
via lldb-commits
lldb-commits at lists.llvm.org
Sat Jun 6 09:26:36 PDT 2026
Author: Jonas Devlieghere
Date: 2026-06-06T09:26:32-07:00
New Revision: 9aef31502094e2b5c997683a6d624aaf39f5bd50
URL: https://github.com/llvm/llvm-project/commit/9aef31502094e2b5c997683a6d624aaf39f5bd50
DIFF: https://github.com/llvm/llvm-project/commit/9aef31502094e2b5c997683a6d624aaf39f5bd50.diff
LOG: [lldb] Add SBDebugger::SetTerminalDimensions to set width and height atomically (#201965)
Terminal width and height were communicated to the debugger separately,
via SetTerminalWidth() and SetTerminalHeight(). Each notified the
IOHandler and the statusline, so on a resize they recomputed their
layout twice: once with one dimension updated and the other still stale.
Add Debugger::SetTerminalDimensions(width, height) (exposed through
SBDebugger) that updates both properties before notifying, and
reimplement the single-axis setters and the driver's resize handler in
terms of it.
Also fix SBDebugger::GetTerminalHeight(), which returned the width.
Added:
Modified:
lldb/include/lldb/API/SBDebugger.h
lldb/include/lldb/Core/Debugger.h
lldb/source/API/SBDebugger.cpp
lldb/source/Core/Debugger.cpp
lldb/test/API/python_api/debugger/TestDebuggerAPI.py
lldb/tools/driver/Driver.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h
index 688fc9197965c..14b8350902811 100644
--- a/lldb/include/lldb/API/SBDebugger.h
+++ b/lldb/include/lldb/API/SBDebugger.h
@@ -517,14 +517,22 @@ class LLDB_API SBDebugger {
uint32_t GetTerminalWidth() const;
/// Set the terminal width.
+ LLDB_DEPRECATED_FIXME("Use SetTerminalDimensions",
+ "SetTerminalDimensions(uint32_t, uint32_t)")
void SetTerminalWidth(uint32_t term_width);
/// Get the terminal height.
uint32_t GetTerminalHeight() const;
/// Set the terminal height.
+ LLDB_DEPRECATED_FIXME("Use SetTerminalDimensions",
+ "SetTerminalDimensions(uint32_t, uint32_t)")
void SetTerminalHeight(uint32_t term_height);
+ /// Set the terminal width and height together. Prefer this over the
+ /// single-axis setters when both are known, e.g. when handling a resize.
+ void SetTerminalDimensions(uint32_t term_width, uint32_t term_height);
+
/// Get the unique ID of this debugger.
lldb::user_id_t GetID();
diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index c5242b639a31b..179ef0f38d940 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -300,6 +300,10 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
bool SetTerminalHeight(uint64_t term_height);
+ /// Set the terminal width and height together, so observers are notified
+ /// once with both dimensions current.
+ bool SetTerminalDimensions(uint64_t term_width, uint64_t term_height);
+
llvm::StringRef GetPrompt() const;
llvm::StringRef GetPromptAnsiPrefix() const;
diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index 0f1708c26b149..c0c7f93c0b87e 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -1338,7 +1338,7 @@ void SBDebugger::SetTerminalWidth(uint32_t term_width) {
uint32_t SBDebugger::GetTerminalHeight() const {
LLDB_INSTRUMENT_VA(this);
- return (m_opaque_sp ? m_opaque_sp->GetTerminalWidth() : 0);
+ return (m_opaque_sp ? m_opaque_sp->GetTerminalHeight() : 0);
}
void SBDebugger::SetTerminalHeight(uint32_t term_height) {
@@ -1348,6 +1348,14 @@ void SBDebugger::SetTerminalHeight(uint32_t term_height) {
m_opaque_sp->SetTerminalHeight(term_height);
}
+void SBDebugger::SetTerminalDimensions(uint32_t term_width,
+ uint32_t term_height) {
+ LLDB_INSTRUMENT_VA(this, term_width, term_height);
+
+ if (m_opaque_sp)
+ m_opaque_sp->SetTerminalDimensions(term_width, term_height);
+}
+
const char *SBDebugger::GetPrompt() const {
LLDB_INSTRUMENT_VA(this);
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 0f7be00aad0d3..9a75c5eb407c5 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -463,19 +463,7 @@ uint64_t Debugger::GetTerminalWidth() const {
}
bool Debugger::SetTerminalWidth(uint64_t term_width) {
- const uint32_t idx = ePropertyTerminalWidth;
- const bool success = SetPropertyAtIndex(idx, term_width);
-
- if (auto handler_sp = m_io_handler_stack.Top())
- handler_sp->TerminalSizeChanged();
-
- {
- std::lock_guard<std::mutex> guard(m_statusline_mutex);
- if (m_statusline)
- m_statusline->TerminalSizeChanged();
- }
-
- return success;
+ return SetTerminalDimensions(term_width, GetTerminalHeight());
}
uint64_t Debugger::GetTerminalHeight() const {
@@ -485,8 +473,17 @@ uint64_t Debugger::GetTerminalHeight() const {
}
bool Debugger::SetTerminalHeight(uint64_t term_height) {
- const uint32_t idx = ePropertyTerminalHeight;
- const bool success = SetPropertyAtIndex(idx, term_height);
+ return SetTerminalDimensions(GetTerminalWidth(), term_height);
+}
+
+bool Debugger::SetTerminalDimensions(uint64_t term_width,
+ uint64_t term_height) {
+ // Set both properties before notifying, so observers never recompute from a
+ // mix of fresh and stale dimensions.
+ const bool width_success =
+ SetPropertyAtIndex(ePropertyTerminalWidth, term_width);
+ const bool height_success =
+ SetPropertyAtIndex(ePropertyTerminalHeight, term_height);
if (auto handler_sp = m_io_handler_stack.Top())
handler_sp->TerminalSizeChanged();
@@ -497,7 +494,7 @@ bool Debugger::SetTerminalHeight(uint64_t term_height) {
m_statusline->TerminalSizeChanged();
}
- return success;
+ return width_success && height_success;
}
bool Debugger::GetUseExternalEditor() const {
diff --git a/lldb/test/API/python_api/debugger/TestDebuggerAPI.py b/lldb/test/API/python_api/debugger/TestDebuggerAPI.py
index 488878b0436cd..f5c9c007d407b 100644
--- a/lldb/test/API/python_api/debugger/TestDebuggerAPI.py
+++ b/lldb/test/API/python_api/debugger/TestDebuggerAPI.py
@@ -42,6 +42,25 @@ def test_debugger_delete_invalid_target(self):
self.assertFalse(target.IsValid())
self.dbg.DeleteTarget(target)
+ def test_terminal_dimensions(self):
+ """Test the SBDebugger terminal width/height accessors and the combined
+ SetTerminalDimensions() setter."""
+ # SetTerminalDimensions updates both axes at once.
+ self.dbg.SetTerminalDimensions(143, 47)
+ self.assertEqual(self.dbg.GetTerminalWidth(), 143)
+ # Regression test: GetTerminalHeight() used to return the width.
+ self.assertEqual(self.dbg.GetTerminalHeight(), 47)
+
+ # The single-axis setters change only their own dimension and leave the
+ # other one intact (they are implemented in terms of the combined call).
+ self.dbg.SetTerminalWidth(99)
+ self.assertEqual(self.dbg.GetTerminalWidth(), 99)
+ self.assertEqual(self.dbg.GetTerminalHeight(), 47)
+
+ self.dbg.SetTerminalHeight(31)
+ self.assertEqual(self.dbg.GetTerminalWidth(), 99)
+ self.assertEqual(self.dbg.GetTerminalHeight(), 31)
+
def test_debugger_internal_variables(self):
"""Ensure that SBDebugger reachs the same instance of properties
regardless CommandInterpreter's context initialization"""
diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp
index 2bb77d275138e..a66552e0428bf 100644
--- a/lldb/tools/driver/Driver.cpp
+++ b/lldb/tools/driver/Driver.cpp
@@ -648,12 +648,15 @@ void Driver::UpdateWindowSize() {
struct winsize window_size;
if ((isatty(STDIN_FILENO) != 0) &&
::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) {
- if (window_size.ws_col > 0)
- m_debugger.SetTerminalWidth(window_size.ws_col);
+ if (window_size.ws_col > 0) {
+ // Set both dimensions together to avoid recomputing from a stale value.
#ifndef _WIN32
- if (window_size.ws_row > 0)
- m_debugger.SetTerminalHeight(window_size.ws_row);
+ m_debugger.SetTerminalDimensions(window_size.ws_col, window_size.ws_row);
+#else
+ m_debugger.SetTerminalDimensions(window_size.ws_col,
+ m_debugger.GetTerminalHeight());
#endif
+ }
}
}
More information about the lldb-commits
mailing list