From abed5664a39b285a909c8af89084d9fe5718cf20 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Thu, 15 May 2025 13:43:07 -0700 Subject: [PATCH] The Swift `object description` expression was being run without setting "IgnoreBreakpointsInExpressions", so it was stopping on breakpoints. That's not how the ObjC object description is run, and is not what people expect here. I added the setting to the options in the Swift case, and added a test that we don't stop on breakpoints in the Object Description expression. --- .../Swift/SwiftLanguageRuntime.cpp | 3 +- .../swift/po/val_types/TestSwiftPOValTypes.py | 38 ++++++++++++++++++- .../API/lang/swift/po/val_types/main.swift | 22 +++++------ 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp index f3b449128d3e2..f57610d15787f 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp @@ -922,9 +922,10 @@ llvm::Error SwiftLanguageRuntime::RunObjectDescriptionExpr( Log *log(GetLog(LLDBLog::DataFormatters | LLDBLog::Expressions)); ValueObjectSP result_sp; EvaluateExpressionOptions eval_options; + eval_options.SetUnwindOnError(true); eval_options.SetLanguage(lldb::eLanguageTypeSwift); eval_options.SetSuppressPersistentResult(true); - eval_options.SetGenerateDebugInfo(true); + eval_options.SetIgnoreBreakpoints(true); eval_options.SetTimeout(GetProcess().GetUtilityExpressionTimeout()); StackFrameSP frame_sp = object.GetFrameSP(); diff --git a/lldb/test/API/lang/swift/po/val_types/TestSwiftPOValTypes.py b/lldb/test/API/lang/swift/po/val_types/TestSwiftPOValTypes.py index d773710c0d159..3a7c936d4169c 100644 --- a/lldb/test/API/lang/swift/po/val_types/TestSwiftPOValTypes.py +++ b/lldb/test/API/lang/swift/po/val_types/TestSwiftPOValTypes.py @@ -9,7 +9,41 @@ # See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors # # ------------------------------------------------------------------------------ -import lldbsuite.test.lldbinline as lldbinline +import lldb +import lldbsuite.test +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * from lldbsuite.test.decorators import * -lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest]) +class TestPOValueTypes(TestBase): + + def test_value_types(self): + """Test 'po' on a variety of value types with and without custom descriptions.""" + self.build() + (_,_,_,_) = lldbutil.run_to_source_breakpoint(self, "Break here to run tests", lldb.SBFileSpec("main.swift")) + + self.expect("po dm", substrs=['a', '12', 'b', '24']) + self.expect("po cm", substrs=['c', '36']) + self.expect("po cm", substrs=['12', '24'], matching=False) + self.expect("po cs", substrs=['CustomDebugStringConvertible']) + self.expect("po cs", substrs=['CustomStringConvertible'], matching=False) + self.expect("po cs", substrs=['a', '12', 'b', '24']) + self.expect("script lldb.frame.FindVariable('cs').GetObjectDescription()", substrs=['a', '12', 'b', '24']) + self.expect("po (12,24,36,48)", substrs=['12', '24', '36', '48']) + self.expect("po (dm as Any, cm as Any,48 as Any)", substrs=['12', '24', '36', '48']) + self.expect("po patatino", substrs=['foo']) + + def test_ignore_bkpts_in_po(self): + """Run a po expression with a breakpoint in the debugDescription, make sure we don't hit it.""" + + self.build() + main_spec = lldb.SBFileSpec("main.swift") + (target, process, thread, _) = lldbutil.run_to_source_breakpoint(self, "Break here to run tests", main_spec) + po_bkpt = target.BreakpointCreateBySourceRegex("Breakpoint in debugDescription", main_spec) + + # As part of the po expression we should auto-continue past the breakpoint so this succeeds: + self.expect("po cs", substrs=['CustomDebugStringConvertible']) + self.assertEqual(po_bkpt.GetHitCount(), 1, "Did hit the breakpoint") + + + diff --git a/lldb/test/API/lang/swift/po/val_types/main.swift b/lldb/test/API/lang/swift/po/val_types/main.swift index 4aa62e07b2ed9..5312791316d34 100644 --- a/lldb/test/API/lang/swift/po/val_types/main.swift +++ b/lldb/test/API/lang/swift/po/val_types/main.swift @@ -16,25 +16,21 @@ struct CustomSummary : CustomStringConvertible, CustomDebugStringConvertible { var a = 12 var b = 24 - var description: String { return "CustomStringConvertible" } - var debugDescription: String { return "CustomDebugStringConvertible" } + var description: String { + return "CustomStringConvertible" + } + var debugDescription: String { + return "CustomDebugStringConvertible" // Breakpoint in debugDescription + } } func main() { var dm = DefaultMirror() var cm = CustomMirror() var cs = CustomSummary() - var patatino = "foo" //% self.expect("image list") - print("yay I am done!") //% self.expect("po dm", substrs=['a', '12', 'b', '24']) - //% self.expect("po cm", substrs=['c', '36']) - //% self.expect("po cm", substrs=['12', '24'], matching=False) - //% self.expect("po cs", substrs=['CustomDebugStringConvertible']) - //% self.expect("po cs", substrs=['CustomStringConvertible'], matching=False) - //% self.expect("po cs", substrs=['a', '12', 'b', '24']) - //% self.expect("script lldb.frame.FindVariable('cs').GetObjectDescription()", substrs=['a', '12', 'b', '24']) - //% self.expect("po (12,24,36,48)", substrs=['12', '24', '36', '48']) - //% self.expect("po (dm as Any, cm as Any,48 as Any)", substrs=['12', '24', '36', '48']) - //% self.expect("po patatino", substrs=['foo']) + var patatino = "foo" + + print("yay I am done!") // Break here to run tests. } main()