Index: lldb/include/lldb/Core/DebuggerEvents.h =================================================================== --- lldb/include/lldb/Core/DebuggerEvents.h +++ lldb/include/lldb/Core/DebuggerEvents.h @@ -32,6 +32,7 @@ static const ProgressEventData *GetEventDataFromEvent(const Event *event_ptr); uint64_t GetID() const { return m_id; } + bool IsFinite() const { return m_total != UINT64_MAX; } uint64_t GetCompleted() const { return m_completed; } uint64_t GetTotal() const { return m_total; } const std::string &GetMessage() const { return m_message; } Index: lldb/source/Core/Debugger.cpp =================================================================== --- lldb/source/Core/Debugger.cpp +++ lldb/source/Core/Debugger.cpp @@ -1857,11 +1857,26 @@ output->Printf( "%s", ansi::FormatAnsiTerminalCodes(ansi_prefix, use_color).c_str()); - // Print the progress message. + // Trim the progress message if it exceeds the window's width and print it. std::string message = data->GetMessage(); - if (data->GetTotal() != UINT64_MAX) { + uint64_t progress_total = data->GetTotal(); + uint32_t term_width = GetTerminalWidth(); + + size_t prefix_width = 0; + if (data->IsFinite()) { + prefix_width += 4; // '[%PRIu64/%PRIu64] %s' + prefix_width += std::to_string(progress_total).size() * 2; + } + + const size_t suffix_width = 3; // %s... + + if (message.size() + prefix_width + suffix_width >= term_width) + message.erase(message.begin() + term_width - prefix_width - suffix_width, + message.end()); + + if (data->IsFinite()) { output->Printf("[%" PRIu64 "/%" PRIu64 "] %s...", data->GetCompleted(), - data->GetTotal(), message.c_str()); + progress_total, message.c_str()); } else { output->Printf("%s...", message.c_str()); } Index: lldb/test/API/functionalities/progress_reporting/TestTrimmedProgressReporting.py =================================================================== --- /dev/null +++ lldb/test/API/functionalities/progress_reporting/TestTrimmedProgressReporting.py @@ -0,0 +1,38 @@ +""" +Test resizing in our IOHandlers. +""" + +import os +import pexpect + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test.lldbpexpect import PExpectTest + +class TestTrimmedProgressReporting(PExpectTest): + + mydir = TestBase.compute_mydir(__file__) + + # PExpect uses many timeouts internally and doesn't play well + # under ASAN on a loaded machine.. + @skipIfAsan + @skipIfEditlineSupportMissing + @skipIf(oslist=["linux"], archs=["arm", "aarch64"]) + def test_resize(self): + self.build() + # Start with a small window + self.launch(executable=self.getBuildArtifact("a.out"), + dimensions=(5,5), timeout=1) + + # Now resize to something bigger + self.child.setwinsize(100,500) + + patterns = ['Locating external symbol file for', + 'Parsing symbol table for', pexpect.EOF, pexpect.TIMEOUT] + + match_index = self.child.expect(patterns) + + self.quit() + + self.assertTrue(match_index, len(patterns) - 1) # match TIMEOUT