[Lldb-commits] [PATCH] D144904: [Linux] Add kernel.yama.ptrace_scope note when ptrace fails to attach.
DavidSpickett accepted this revision. DavidSpickett added a comment. This revision is now accepted and ready to land. LGTM Comment at: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp:235 +std::error_code(errno, std::generic_category()), +"The current value of ptrace_scope is %d, which can cause ptrace to " +"fail to attach to a running process. To fix this, run:\n" rupprecht wrote: > DavidSpickett wrote: > > Tell me if I understand correctly. This error is only used if you've > > already failed to attach. So if you had a value of 1 or 2, but attaching > > worked fine, you wouldn't see this. > > > > Which is why you've said "which can cause" instead of "does cause". As > > there are some situations with 1 or 2 that do work. > That's exactly right, at least to my understanding. > > Level 3 is basically a global kill switch -- no ptrace ever, in any context, > even if you're root. The only way to undo that is to reboot, and even then, a > hardened machine might set it to 3 in some startup config, so the only way to > undo it is remove that setting and *then* reboot. > > At level 2 you need `CAP_SYS_PTRACE` to ptrace an arbitrary process, i.e. you > need to be root or have some root-like capability granted. So IIUC, `sudo > lldb -n blah` should still work at that level. > > At level 1, ptrace is allowed for anything LLDB launches, as there's a > parent-child relationship, but usually not arbitrary other processes. > However, an arbitrary process that wants to be debugged could call > `prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...)` or `ptrace(PTRACE_TRACEME, > ...)`, in which case a ptrace on that process should be successful. We could > suggest these as other workarounds, but common advice is just to use `sudo > sysctl -w kernel.yama.ptrace_scope=0`, and that's certainly a lot easier to > fit into an error message. > > Admittedly, using "which can cause" is sort of pedantic -- it can cause > ptrace to fail, but there are situations above where it doesn't -- but > failing in ptrace with EPERM followed by a non-zero ptrace_scope value is a > very strong signal that this *is* the reason. I can't come up with a scenario > where it isn't the case, but I this isn't my area of expertise. > > The difference between 1 and 2 is subtle enough that I think we can use the > same error message in each case, but if we also used it for level 3, that > would just frustrate the user who tries to figure out why `sudo sysctl -w > kernel.yama.ptrace_scope=0` doesn't work. But in general, I'd be happy with > whatever wording people would find more useful. Sounds good to me. > At level 2 you need CAP_SYS_PTRACE to ptrace an arbitrary process I've had this problem with docker containers started in certain ways, this error message will be really useful there. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D144904/new/ https://reviews.llvm.org/D144904 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] fad6010 - [lldb/test] Update error message in debug-types-signature-loop.s
Author: Pavel Labath Date: 2023-03-01T13:51:58+01:00 New Revision: fad60105ace546deb219adb14e0eef01a2b6c9d6 URL: https://github.com/llvm/llvm-project/commit/fad60105ace546deb219adb14e0eef01a2b6c9d6 DIFF: https://github.com/llvm/llvm-project/commit/fad60105ace546deb219adb14e0eef01a2b6c9d6.diff LOG: [lldb/test] Update error message in debug-types-signature-loop.s The error message changed in D144664. Added: Modified: lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-signature-loop.s Removed: diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-signature-loop.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-signature-loop.s index d0d0fd5705a45..64b835353ed4e 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-signature-loop.s +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-signature-loop.s @@ -4,7 +4,7 @@ # RUN: ld.lld %t.o -o %t # RUN: %lldb %t -o "target variable e" -b | FileCheck %s -# CHECK: e = +# CHECK: Error: 'Unable to determine byte size.' .type e,@object # @e .section.rodata,"a",@progbits ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D144665: Use Resume not PrivateResume when asynchronously continuing after the start at stop
stella.stamenova added a comment. Looks like the new test is failing on the windows lldb bot: https://lab.llvm.org/buildbot/#/builders/83/builds/29680. The buildbot was already red because of `TestCommandScript.py`, so you might have missed this. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D144665/new/ https://reviews.llvm.org/D144665 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D142792: Add SBValue::GetValueAsAddress(), strip off ptrauth, TBI, MTE bits on AArch64 systems
jasonmolenda updated this revision to Diff 501574. jasonmolenda added a comment. Clean up the test case - the C file and python file - to address David's feedback and test it more thoroughly. Fix `ValueObjectPrinter::PrintValueAndSummaryIfNeeded()` to only add the `actual=hex` if this is a pointer type. I think we're all done with this one. The test file now creates three variables, a pointer to a stack, a pointer to a global, and a function pointer, with TBI bits and without. e.g. runCmd: frame variable output: (int) count = 5 (int *) count_p = 0x00016fdff258 (intptr_t) scratch = 3458764518115524608 (int *) count_invalid_p = 0x30016fdff258 (actual=0x16fdff258) (int (*)(...)) main_p = 0x00013f28 (a.out`main at main.c:5) (int (*)(...)) main_invalid_p = 0x30013f28 (actual=0x13f28) (a.out`main at main.c:5) (int *) global_p = 0x00014000 (int *) global_invalid_p = 0x30014000 (actual=0x14000) We're not printing the symbol name for the `global_p` and `global_invalid_p` - this is unrelated to TBI, I might look into that later, whether it should print the name of the symbol here in the description. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142792/new/ https://reviews.llvm.org/D142792 Files: lldb/bindings/interface/SBValueDocstrings.i lldb/include/lldb/API/SBValue.h lldb/include/lldb/Core/ValueObject.h lldb/source/API/SBValue.cpp lldb/source/Core/ValueObject.cpp lldb/source/DataFormatters/ValueObjectPrinter.cpp lldb/test/API/api/clear-sbvalue-nonadressable-bits/Makefile lldb/test/API/api/clear-sbvalue-nonadressable-bits/TestClearSBValueNonAddressableBits.py lldb/test/API/api/clear-sbvalue-nonadressable-bits/main.c Index: lldb/test/API/api/clear-sbvalue-nonadressable-bits/main.c === --- /dev/null +++ lldb/test/API/api/clear-sbvalue-nonadressable-bits/main.c @@ -0,0 +1,27 @@ +#include +#include +int global = 10; + +int main() { + int count = 5; + int *count_p = &count; + + // Add some metadata in the top byte (this will crash unless the + // test is running with TBI enabled, but we won't dereference it) + + intptr_t scratch = (intptr_t)count_p; + scratch |= (3ULL << 60); + int *count_invalid_p = (int *)scratch; + + int (*main_p)() = main; + scratch = (intptr_t)main_p; + scratch |= (3ULL << 60); + int (*main_invalid_p)() = (int (*)())scratch; + + int *global_p = &global; + scratch = (intptr_t)global_p; + scratch |= (3ULL << 60); + int *global_invalid_p = (int *)scratch; + + return count; // break here +} Index: lldb/test/API/api/clear-sbvalue-nonadressable-bits/TestClearSBValueNonAddressableBits.py === --- /dev/null +++ lldb/test/API/api/clear-sbvalue-nonadressable-bits/TestClearSBValueNonAddressableBits.py @@ -0,0 +1,59 @@ +"""Test that SBValue clears non-addressable bits""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestClearSBValueNonAddressableBits(TestBase): + +NO_DEBUG_INFO_TESTCASE = True + +# On AArch64 systems, the top bits that are not used for +# addressing may be used for TBI, MTE, and/or pointer +# authentication. +@skipIf(archs=no_match(['aarch64', 'arm64', 'arm64e'])) + +# Only run this test on systems where TBI is known to be +# enabled, so the address mask will clear the TBI bits. +@skipUnlessPlatform(["linux"]+lldbplatformutil.getDarwinOSTriples()) + +def test(self): +self.source = 'main.c' +self.build() +(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "break here", lldb.SBFileSpec(self.source, False)) + +if self.TraceOn(): +self.runCmd ("frame variable") +self.runCmd ("frame variable &count &global") + +frame = thread.GetFrameAtIndex(0) + +count_p = frame.FindVariable("count_p") +count_invalid_p = frame.FindVariable("count_invalid_p") +self.assertEqual(count_p.GetValueAsUnsigned(), count_invalid_p.GetValueAsAddress()) +self.assertNotEqual(count_invalid_p.GetValueAsUnsigned(), count_invalid_p.GetValueAsAddress()) +self.assertEqual(5, count_p.Dereference().GetValueAsUnsigned()) +self.assertEqual(5, count_invalid_p.Dereference().GetValueAsUnsigned()) +strm = lldb.SBStream() +count_invalid_p.GetDescription(strm) +self.assertIn("actual=0x", strm.GetData()) + +global_p = frame.FindVariable("global_p") +global_invalid_p = frame.FindVariable("global_invalid_p") +self.assertEqual(global_p.GetValueAsUnsigned(), global_invalid_p.GetValueAsAddress()) +self.assertNotEqual(global_invalid_p.GetValueAsUnsigned(), global_invalid_p.GetValueAsAddress()) +self.a
[Lldb-commits] [PATCH] D144937: [LLDB] Expose several methods in SBWatchpoint
delcypher updated this revision to Diff 501582. delcypher edited the summary of this revision. delcypher added a comment. - Fix nits Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D144937/new/ https://reviews.llvm.org/D144937 Files: lldb/bindings/interface/SBWatchpointDocstrings.i lldb/docs/python_api_enums.rst lldb/include/lldb/API/SBType.h lldb/include/lldb/API/SBWatchpoint.h lldb/include/lldb/lldb-enumerations.h lldb/source/API/SBWatchpoint.cpp lldb/test/API/python_api/watchpoint/TestSetWatchpoint.py lldb/test/API/python_api/watchpoint/watchlocation/TestSetWatchlocation.py Index: lldb/test/API/python_api/watchpoint/watchlocation/TestSetWatchlocation.py === --- lldb/test/API/python_api/watchpoint/watchlocation/TestSetWatchlocation.py +++ lldb/test/API/python_api/watchpoint/watchlocation/TestSetWatchlocation.py @@ -64,6 +64,15 @@ self.DebugSBValue(value) self.DebugSBValue(pointee) +# Check some API calls return expected values +self.assertEqual(watchpoint.GetWatchValueKind(), + lldb.eWatchPointValueKindExpression) +# FIXME: The spec should probably be 'g_char_ptr' +self.assertEqual(watchpoint.GetWatchSpec(), None) +self.assertEqual(watchpoint.GetType().GetDisplayTypeName(), 'char') +self.assertFalse(watchpoint.IsWatchingReads()) +self.assertTrue(watchpoint.IsWatchingWrites()) + # Hide stdout if not running with '-t' option. if not self.TraceOn(): self.HideStdout() Index: lldb/test/API/python_api/watchpoint/TestSetWatchpoint.py === --- lldb/test/API/python_api/watchpoint/TestSetWatchpoint.py +++ lldb/test/API/python_api/watchpoint/TestSetWatchpoint.py @@ -19,12 +19,24 @@ # Find the line number to break inside main(). self.line = line_number( self.source, '// Set break point at this line.') +self.build() # Read-write watchpoints not supported on SystemZ @expectedFailureAll(archs=['s390x']) def test_watch_val(self): """Exercise SBValue.Watch() API to set a watchpoint.""" -self.build() +self._test_watch_val(variable_watchpoint=False) +pass + +@expectedFailureAll(archs=['s390x']) +def test_watch_variable(self): +""" + Exercise some watchpoint APIs when the watchpoint + is created as a variable watchpoint. +""" +self._test_watch_val(variable_watchpoint=True) + +def _test_watch_val(self, variable_watchpoint): exe = self.getBuildArtifact("a.out") # Create a target by the debugger. @@ -50,12 +62,40 @@ frame0 = thread.GetFrameAtIndex(0) # Watch 'global' for read and write. -value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) -error = lldb.SBError() -watchpoint = value.Watch(True, True, True, error) -self.assertTrue(value and watchpoint, +if variable_watchpoint: +# FIXME: There should probably be an API to create a +# variable watchpoint. +self.runCmd('watchpoint set variable -w read_write -- global') +watchpoint = target.GetWatchpointAtIndex(0) +self.assertEqual(watchpoint.GetWatchValueKind(), + lldb.eWatchPointValueKindVariable) +self.assertEqual(watchpoint.GetWatchSpec(), 'global') +# Synthesize an SBValue from the watchpoint +watchpoint_addr = lldb.SBAddress(watchpoint.GetWatchAddress(), + target) +value = target.CreateValueFromAddress( +watchpoint.GetWatchSpec(), +watchpoint_addr, watchpoint.GetType()) +else: +value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) +error = lldb.SBError() +watchpoint = value.Watch(True, True, True, error) +self.assertTrue(value and watchpoint, "Successfully found the variable and set a watchpoint") -self.DebugSBValue(value) +self.DebugSBValue(value) +self.assertEqual(watchpoint.GetWatchValueKind(), + lldb.eWatchPointValueKindExpression) +# FIXME: The spec should probably be '&global' given that the kind +# is reported as eWatchPointValueKindExpression. If the kind is +# actually supposed to be eWatchPointValueKindVariable then the spec +# should probably be 'global'. +self.assertEqual(watchpoint.GetWatchSpec(), None) + +self.assertEqual(watchpoint.GetType().GetDisplayTypeName(), 'int32_t') +self.assertEqual(value.GetName(), 'global') +self.assertEqual(value.GetType(), watchpoint.GetTyp
[Lldb-commits] [PATCH] D144937: [LLDB] Expose several methods in SBWatchpoint
delcypher marked 2 inline comments as done. delcypher added a comment. Thanks for the review and approval. I've the fixed the nits so I'm going to land. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D144937/new/ https://reviews.llvm.org/D144937 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 55a363f - [LLDB] Expose several methods in SBWatchpoint
Author: Dan Liew Date: 2023-03-01T11:15:05-08:00 New Revision: 55a363fea18b20a81e8ebb9518997a3bda602f32 URL: https://github.com/llvm/llvm-project/commit/55a363fea18b20a81e8ebb9518997a3bda602f32 DIFF: https://github.com/llvm/llvm-project/commit/55a363fea18b20a81e8ebb9518997a3bda602f32.diff LOG: [LLDB] Expose several methods in SBWatchpoint This patch adds the following methods: * `GetType()` * `GetWatchValueKind()` * `GetWatchSpec()` * `IsWatchingReads()` * `IsWatchingWrites()` These mostly expose methods that `lldb_private::Watchpoint` already had. Tests are included that exercise these new methods. The motivation for exposing these are as follows: * `GetType()` - With this information and the address from a watchpoint it is now possible to construct an SBValue from an SBWatchpoint. Previously this wasn't possible. The included test case illustrates doing this. * `GetWatchValueKind()` - This allows the caller to determine whether the watchpoint is a variable watchpoint or an expression watchpoint. A new enum (`WatchpointValueKind`) has been introduced to represent the return values. Unfortunately the name `WatchpointKind` was already taken. * `GetWatchSpec()` - This allows (at least for variable watchpoints) to use a sensible name for SBValues created from an SBWatchpoint. * `IsWatchingReads()` - This allow checking if a watchpoint is monitoring read accesses. * `IsWatchingWRites()` - This allow checking if a watchpoint is monitoring write accesses. rdar://105606978 Reviewers: jingham, mib, bulbazord, jasonmolenda, JDevlieghere Differential Revision: https://reviews.llvm.org/D144937 Added: Modified: lldb/bindings/interface/SBWatchpointDocstrings.i lldb/docs/python_api_enums.rst lldb/include/lldb/API/SBType.h lldb/include/lldb/API/SBWatchpoint.h lldb/include/lldb/lldb-enumerations.h lldb/source/API/SBWatchpoint.cpp lldb/test/API/python_api/watchpoint/TestSetWatchpoint.py lldb/test/API/python_api/watchpoint/watchlocation/TestSetWatchlocation.py Removed: diff --git a/lldb/bindings/interface/SBWatchpointDocstrings.i b/lldb/bindings/interface/SBWatchpointDocstrings.i index 9bee8c751ef3b..4eb7b136282dc 100644 --- a/lldb/bindings/interface/SBWatchpointDocstrings.i +++ b/lldb/bindings/interface/SBWatchpointDocstrings.i @@ -19,3 +19,30 @@ watchpoints of the target." %feature("docstring", " The watchpoint stops only if the condition expression evaluates to true." ) lldb::SBWatchpoint::SetCondition; + +%feature("docstring", " +Returns the type recorded when the watchpoint was created. For variable +watchpoints it is the type of the watched variable. For expression +watchpoints it is the type of the provided expression." +) lldb::SBWatchpoint::GetType; + +%feature("docstring", " +Returns the kind of value that was watched when the watchpoint was created. +Returns one of the following eWatchPointValueKindVariable, +eWatchPointValueKindExpression, eWatchPointValueKindInvalid. +" +) lldb::SBWatchpoint::GetWatchValueKind; + +%feature("docstring", " +Get the spec for the watchpoint. For variable watchpoints this is the name +of the variable. For expression watchpoints it is empty +(may change in the future)." +) lldb::SBWatchpoint::GetWatchSpec; + +%feature("docstring", " +Returns true if the watchpoint is watching reads. Returns false otherwise." +) lldb::SBWatchpoint::IsWatchingReads; + +%feature("docstring", " +Returns true if the watchpoint is watching writes. Returns false otherwise." +) lldb::SBWatchpoint::IsWatchingWrites; diff --git a/lldb/docs/python_api_enums.rst b/lldb/docs/python_api_enums.rst index 6ae73df68c8ab..8fe2b7f301306 100644 --- a/lldb/docs/python_api_enums.rst +++ b/lldb/docs/python_api_enums.rst @@ -1407,3 +1407,24 @@ The result from a command interpreter run. .. py:data:: eCommandInterpreterResultQuitRequested Stopped because quit was requested. + + +.. _WatchPointValueKind: + +WatchPointValueKind +--- + +The type of value that the watchpoint was created to monitor. + +.. py:data:: eWatchPointValueKindInvalid + + Invalid kind. + +.. py:data:: eWatchPointValueKindVariable + + Watchpoint was created watching a variable + +.. py:data:: eWatchPointValueKindExpression + + Watchpoint was created watching the result of an expression that was + evaluated at creation time. diff --git a/lldb/include/lldb/API/SBType.h b/lldb/include/lldb/API/SBType.h index 06433b0891beb..930f72eb36668 100644 --- a/lldb/include/lldb/API/SBType.h +++ b/lldb/include/lldb/API/SBType.h @@ -239,6 +239,7 @@ class SBType { friend class SBTypeMemberFunction; friend class SBTypeList; friend class SBValue; + friend class SBWatchpoint; SBType(const lldb_private::CompilerType &); SBType(const lldb::TypeSP &); diff --git a/lldb/include/lldb/API/SBWatchpoint.h b/lldb/
[Lldb-commits] [PATCH] D144937: [LLDB] Expose several methods in SBWatchpoint
This revision was automatically updated to reflect the committed changes. Closed by commit rG55a363fea18b: [LLDB] Expose several methods in SBWatchpoint (authored by delcypher). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D144937/new/ https://reviews.llvm.org/D144937 Files: lldb/bindings/interface/SBWatchpointDocstrings.i lldb/docs/python_api_enums.rst lldb/include/lldb/API/SBType.h lldb/include/lldb/API/SBWatchpoint.h lldb/include/lldb/lldb-enumerations.h lldb/source/API/SBWatchpoint.cpp lldb/test/API/python_api/watchpoint/TestSetWatchpoint.py lldb/test/API/python_api/watchpoint/watchlocation/TestSetWatchlocation.py Index: lldb/test/API/python_api/watchpoint/watchlocation/TestSetWatchlocation.py === --- lldb/test/API/python_api/watchpoint/watchlocation/TestSetWatchlocation.py +++ lldb/test/API/python_api/watchpoint/watchlocation/TestSetWatchlocation.py @@ -64,6 +64,15 @@ self.DebugSBValue(value) self.DebugSBValue(pointee) +# Check some API calls return expected values +self.assertEqual(watchpoint.GetWatchValueKind(), + lldb.eWatchPointValueKindExpression) +# FIXME: The spec should probably be 'g_char_ptr' +self.assertEqual(watchpoint.GetWatchSpec(), None) +self.assertEqual(watchpoint.GetType().GetDisplayTypeName(), 'char') +self.assertFalse(watchpoint.IsWatchingReads()) +self.assertTrue(watchpoint.IsWatchingWrites()) + # Hide stdout if not running with '-t' option. if not self.TraceOn(): self.HideStdout() Index: lldb/test/API/python_api/watchpoint/TestSetWatchpoint.py === --- lldb/test/API/python_api/watchpoint/TestSetWatchpoint.py +++ lldb/test/API/python_api/watchpoint/TestSetWatchpoint.py @@ -19,12 +19,24 @@ # Find the line number to break inside main(). self.line = line_number( self.source, '// Set break point at this line.') +self.build() # Read-write watchpoints not supported on SystemZ @expectedFailureAll(archs=['s390x']) def test_watch_val(self): """Exercise SBValue.Watch() API to set a watchpoint.""" -self.build() +self._test_watch_val(variable_watchpoint=False) +pass + +@expectedFailureAll(archs=['s390x']) +def test_watch_variable(self): +""" + Exercise some watchpoint APIs when the watchpoint + is created as a variable watchpoint. +""" +self._test_watch_val(variable_watchpoint=True) + +def _test_watch_val(self, variable_watchpoint): exe = self.getBuildArtifact("a.out") # Create a target by the debugger. @@ -50,12 +62,40 @@ frame0 = thread.GetFrameAtIndex(0) # Watch 'global' for read and write. -value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) -error = lldb.SBError() -watchpoint = value.Watch(True, True, True, error) -self.assertTrue(value and watchpoint, +if variable_watchpoint: +# FIXME: There should probably be an API to create a +# variable watchpoint. +self.runCmd('watchpoint set variable -w read_write -- global') +watchpoint = target.GetWatchpointAtIndex(0) +self.assertEqual(watchpoint.GetWatchValueKind(), + lldb.eWatchPointValueKindVariable) +self.assertEqual(watchpoint.GetWatchSpec(), 'global') +# Synthesize an SBValue from the watchpoint +watchpoint_addr = lldb.SBAddress(watchpoint.GetWatchAddress(), + target) +value = target.CreateValueFromAddress( +watchpoint.GetWatchSpec(), +watchpoint_addr, watchpoint.GetType()) +else: +value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) +error = lldb.SBError() +watchpoint = value.Watch(True, True, True, error) +self.assertTrue(value and watchpoint, "Successfully found the variable and set a watchpoint") -self.DebugSBValue(value) +self.DebugSBValue(value) +self.assertEqual(watchpoint.GetWatchValueKind(), + lldb.eWatchPointValueKindExpression) +# FIXME: The spec should probably be '&global' given that the kind +# is reported as eWatchPointValueKindExpression. If the kind is +# actually supposed to be eWatchPointValueKindVariable then the spec +# should probably be 'global'. +self.assertEqual(watchpoint.GetWatchSpec(), None) + +self.assertEqual(watchpoint.GetType().GetDisplayTypeName(), 'int32_t') +self.assertEqual(value.GetName(), 'global') +self.as
[Lldb-commits] [PATCH] D145115: [LLDB][NativePDB] Check string table in PDB files.
zequanwu created this revision. zequanwu added a reviewer: labath. Herald added a subscriber: arphaman. Herald added a project: All. zequanwu requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits. Usually PDB files have a string table (aka: Named Stream "/names" ). PDB for some windows system libraries might not have that. This adds the check for it to avoid crash in the absence of string table. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D145115 Files: lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp Index: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp === --- lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1341,6 +1341,9 @@ llvm::Expected SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii, uint32_t file_id) { + if (!cii.m_strings.hasChecksums() || !cii.m_strings.hasStrings()) +return llvm::make_error(raw_error_code::no_entry); + const auto &checksums = cii.m_strings.checksums().getArray(); const auto &strings = cii.m_strings.strings(); // Indices in this structure are actually offsets of records in the Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp === --- lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp +++ lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp @@ -703,8 +703,12 @@ if (frame_data_it == new_fpo_data.end()) return false; - PDBStringTable &strings = cantFail(index.pdb().getStringTable()); - out_program = cantFail(strings.getStringForID(frame_data_it->FrameFunc)); + auto strings = index.pdb().getStringTable(); + if (!strings) { +consumeError(strings.takeError()); +return false; + } + out_program = cantFail(strings->getStringForID(frame_data_it->FrameFunc)); return true; } Index: lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp === --- lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp +++ lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp @@ -162,9 +162,13 @@ ParseExtendedInfo(m_index, *cci); ParseInlineeLineTableForCompileUnit(*cci); - cci->m_strings.initialize(cci->m_debug_stream.getSubsectionsArray()); - PDBStringTable &strings = cantFail(m_index.pdb().getStringTable()); - cci->m_strings.setStrings(strings.getStringTable()); + auto strings = m_index.pdb().getStringTable(); + if (strings) { +cci->m_strings.initialize(cci->m_debug_stream.getSubsectionsArray()); +cci->m_strings.setStrings(strings->getStringTable()); + } else { +consumeError(strings.takeError()); + } // We want the main source file to always comes first. Note that we can't // just push_back the main file onto the front because `GetMainSourceFile` Index: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp === --- lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1341,6 +1341,9 @@ llvm::Expected SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii, uint32_t file_id) { + if (!cii.m_strings.hasChecksums() || !cii.m_strings.hasStrings()) +return llvm::make_error(raw_error_code::no_entry); + const auto &checksums = cii.m_strings.checksums().getArray(); const auto &strings = cii.m_strings.strings(); // Indices in this structure are actually offsets of records in the Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp === --- lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp +++ lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp @@ -703,8 +703,12 @@ if (frame_data_it == new_fpo_data.end()) return false; - PDBStringTable &strings = cantFail(index.pdb().getStringTable()); - out_program = cantFail(strings.getStringForID(frame_data_it->FrameFunc)); + auto strings = index.pdb().getStringTable(); + if (!strings) { +consumeError(strings.takeError()); +return false; + } + out_program = cantFail(strings->getStringForID(frame_data_it->FrameFunc)); return true; } Index: lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp === --- lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp +++ lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp @@ -162,9 +162,13 @@ ParseExtendedInfo(m_index, *cci); ParseInlineeLineTableForCompileUnit(*cci); -
[Lldb-commits] [PATCH] D144937: [LLDB] Expose several methods in SBWatchpoint
jingham added inline comments. Comment at: lldb/test/API/python_api/watchpoint/TestSetWatchpoint.py:66 +if variable_watchpoint: +# FIXME: There should probably be an API to create a variable watchpoint +self.runCmd('watchpoint set variable -w read_write -- global') delcypher wrote: > delcypher wrote: > > mib wrote: > > > +1, please file an enhancement request :) > > Will do. TBH I'm actually surprised that calling `SBValue::Watch()` doesn't > > create a variable watchpoint. > Actually I'm even more confident this is a bug. If `value.Watch(...)` created > an expression watchpoint you would expect the type to be a `int32_t*` > (because the watched expression would need to have been `&global`), not > `int32_t`. > > However, I think this bug should be fixed in a different commit. There's no guarantee that an SBValue represents a variable. An SBValue backed by a ValueObjectVariable (or a ValueObjectChild whose root object is a ValueObjectVariable) could create a Variable watchpoint. But for instance a typed memory address isn't a variable, nor is an expression result. They don't have scopes, which is the main thing "variable" watchpoints have over expression ones, for instance. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D144937/new/ https://reviews.llvm.org/D144937 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D145124: [lldb] Add variable completion to dwim-print
kastiglione created this revision. kastiglione added a reviewer: aprantl. Herald added a project: All. kastiglione requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits. Enable completion of variables for `dwim-print` command. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D145124 Files: lldb/source/Commands/CommandObjectDWIMPrint.cpp lldb/source/Commands/CommandObjectDWIMPrint.h lldb/test/API/functionalities/completion/TestCompletion.py Index: lldb/test/API/functionalities/completion/TestCompletion.py === --- lldb/test/API/functionalities/completion/TestCompletion.py +++ lldb/test/API/functionalities/completion/TestCompletion.py @@ -36,42 +36,55 @@ def test_frame_variable(self): self.build() -self.main_source = "main.cpp" -self.main_source_spec = lldb.SBFileSpec(self.main_source) -(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, - '// Break here', self.main_source_spec) +_, process, _, _ = lldbutil.run_to_source_breakpoint( +self, '// Break here', lldb.SBFileSpec("main.cpp")) self.assertState(process.GetState(), lldb.eStateStopped) # Since CommandInterpreter has been corrected to update the current execution # context at the beginning of HandleCompletion, we're here explicitly testing # the scenario where "frame var" is completed without any preceding commands. +self.do_test_variable_completion('frame variable') -self.complete_from_to('frame variable fo', - 'frame variable fooo') -self.complete_from_to('frame variable fooo.', - 'frame variable fooo.') -self.complete_from_to('frame variable fooo.dd', - 'frame variable fooo.dd') +def test_dwim_print(self): +self.build() -self.complete_from_to('frame variable ptr_fooo->', - 'frame variable ptr_fooo->') -self.complete_from_to('frame variable ptr_fooo->dd', - 'frame variable ptr_fooo->dd') +_, process, _, _ = lldbutil.run_to_source_breakpoint( +self, '// Break here', lldb.SBFileSpec("main.cpp")) +self.assertState(process.GetState(), lldb.eStateStopped) -self.complete_from_to('frame variable cont', - 'frame variable container') -self.complete_from_to('frame variable container.', - 'frame variable container.MemberVar') -self.complete_from_to('frame variable container.Mem', - 'frame variable container.MemberVar') +# Since CommandInterpreter has been corrected to update the current execution +# context at the beginning of HandleCompletion, we're here explicitly testing +# the scenario where "frame var" is completed without any preceding commands. +self.do_test_variable_completion('dwim-print') -self.complete_from_to('frame variable ptr_cont', - 'frame variable ptr_container') -self.complete_from_to('frame variable ptr_container->', - 'frame variable ptr_container->MemberVar') -self.complete_from_to('frame variable ptr_container->Mem', - 'frame variable ptr_container->MemberVar') + +def do_test_variable_completion(self, command): +self.complete_from_to(f'{command} fo', + f'{command} fooo') +self.complete_from_to(f'{command} fooo.', + f'{command} fooo.') +self.complete_from_to(f'{command} fooo.dd', + f'{command} fooo.dd') + +self.complete_from_to(f'{command} ptr_fooo->', + f'{command} ptr_fooo->') +self.complete_from_to(f'{command} ptr_fooo->dd', + f'{command} ptr_fooo->dd') + +self.complete_from_to(f'{command} cont', + f'{command} container') +self.complete_from_to(f'{command} container.', + f'{command} container.MemberVar') +self.complete_from_to(f'{command} container.Mem', + f'{command} container.MemberVar') + +self.complete_from_to(f'{command} ptr_cont', + f'{command} ptr_container') +self.complete_from_to(f'{command} ptr_container->', + f'{command} ptr_container->MemberVar') +self.complete_from_to(f'{command} ptr_container->Mem', + f'{command} ptr_container->MemberVar') def test_process_attach_dash_dash_con(self): """Test that 'process attach --con' comp
[Lldb-commits] [PATCH] D145136: Add a Debugger interruption mechanism in parallel to the Command Interpreter interruption
jingham created this revision. jingham added reviewers: labath, JDevlieghere, clayborg, jasonmolenda, bulbazord. Herald added a project: All. jingham requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits. I put up an RFC for debugger interruption a while back. This is my version of that RFC. The implementation is based on the way lldb is often used in UI's (as opposed to the simple use in lldb's command driver). In those cases, the lldb client often includes a thread running the LLDB command interpreter so that they can provide an "LLDB Console" window where the user can run commands, and then on other threads they call various SB API's that are used to fill the Threads, Locals, etc. windows. So it seemed the most useful model was to separate interrupting into "Interrupting commands servicing the Console" and "Interrupting work the client is doing on its own behalf." For instance if the client is filling the Locals view, but then the user issues "continue" in the console, the client would want to interrupt filling the Locals view (e.g. interrupt SBFrame.FindVariables()) so that it can continue right away, but not interrupt the user's "continue" command. Similarly, if the user types some command that's producing lots of output, they want to interrupt that but not stop whatever work the client was doing at the same time. Another question is how do we tell "Console" window commands from Client commands? Since we provide a nice API that packages up the "run a command interpreter" behavior, it seemed reasonable to have commands run by the thread servicing RunCommandInterpreter be the "Interpreter" commands, and all other threads belong to the client. This is also convenient because we can programmatically determine which flag we should check when we check the interruption, which allows us to provide a unified API for checking whether an interrupt was requested. Also, the CommandInterpreter does its job Command by Command, so there's a natural boundary on which to take down the interrupt request. However the client program is really the only agent that can know when it wants to start & stop interruption, so instead of a single InterruptCommand with automatic boundaries, I added explicit raise & lower interrupt flag API's. One slight ugliness is that we already have SBCommandInterpreter::WasInterrupted(). I could have just left that as the one interface to query for interruption. But long term, I think it makes more sense to think about this as the Debugger figuring out who to interrupt, so I think an SBDebugger::InterruptRequested API is better. Even though I can't remove the old API, I still added the new one. One other detail you will see in the tests. The current behavior for command interpreter interruption is that if a command is interrupted, we discard the output it has accumulated so far and just return the result "Interrupted..." That's why I had to set the ImmediateOutput file in the test. I'm on the fence about this behavior, so I opted not to change it for now. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D145136 Files: lldb/include/lldb/API/SBCommandInterpreter.h lldb/include/lldb/API/SBDebugger.h lldb/include/lldb/Core/Debugger.h lldb/include/lldb/Interpreter/CommandInterpreter.h lldb/source/API/SBCommandInterpreter.cpp lldb/source/API/SBDebugger.cpp lldb/source/Commands/CommandObjectTarget.cpp lldb/source/Core/Debugger.cpp lldb/source/Interpreter/CommandInterpreter.cpp lldb/test/API/python_api/was_interrupted/Makefile lldb/test/API/python_api/was_interrupted/TestDebuggerInterruption.py lldb/test/API/python_api/was_interrupted/interruptible.py lldb/test/API/python_api/was_interrupted/main.c Index: lldb/test/API/python_api/was_interrupted/main.c === --- /dev/null +++ lldb/test/API/python_api/was_interrupted/main.c @@ -0,0 +1,11 @@ +#include + +int global_test_var = 10; + +int +main() +{ + int test_var = 10; + printf ("Set a breakpoint here: %d.\n", test_var); + return global_test_var; +} Index: lldb/test/API/python_api/was_interrupted/interruptible.py === --- /dev/null +++ lldb/test/API/python_api/was_interrupted/interruptible.py @@ -0,0 +1,93 @@ +import lldb +import threading + +local_data = None + +class LockContainer(threading.local): +def __init__(self, lock, event): +self.lock = lock +self.event = event + +class WelcomeCommand(object): + +def __init__(self, debugger, session_dict): +return + +def get_short_help(self): +return "A command that waits for an interrupt before returning." + +def check_was_interrupted(self, debugger, use_interpreter): +if use_interpreter: +self.was_interrupted = debugger.GetCommandInterpreter().WasInterrupted() +e
[Lldb-commits] [lldb] 9d28e00 - [LLDB] XFAIL TestRunLocker.py on Windows
Author: Muhammad Omair Javaid Date: 2023-03-02T11:05:23+04:00 New Revision: 9d28e00e741cb19684111656803434aceef4c2a0 URL: https://github.com/llvm/llvm-project/commit/9d28e00e741cb19684111656803434aceef4c2a0 DIFF: https://github.com/llvm/llvm-project/commit/9d28e00e741cb19684111656803434aceef4c2a0.diff LOG: [LLDB] XFAIL TestRunLocker.py on Windows Added: Modified: lldb/test/API/python_api/run_locker/TestRunLocker.py Removed: diff --git a/lldb/test/API/python_api/run_locker/TestRunLocker.py b/lldb/test/API/python_api/run_locker/TestRunLocker.py index 191400d6c024f..ff34d47142b41 100644 --- a/lldb/test/API/python_api/run_locker/TestRunLocker.py +++ b/lldb/test/API/python_api/run_locker/TestRunLocker.py @@ -14,11 +14,13 @@ class TestRunLocker(TestBase): NO_DEBUG_INFO_TESTCASE = True +@expectedFailureAll(oslist=["windows"]) def test_run_locker(self): """Test that the run locker is set correctly when we launch""" self.build() self.runlocker_test(False) +@expectedFailureAll(oslist=["windows"]) def test_run_locker_stop_at_entry(self): """Test that the run locker is set correctly when we launch""" self.build() ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 588da01 - Revert "[LLDB] XFAIL TestRunLocker.py on Windows"
Author: Muhammad Omair Javaid Date: 2023-03-02T11:22:25+04:00 New Revision: 588da01621a1f8efd139e677526b64c1e5ecf303 URL: https://github.com/llvm/llvm-project/commit/588da01621a1f8efd139e677526b64c1e5ecf303 DIFF: https://github.com/llvm/llvm-project/commit/588da01621a1f8efd139e677526b64c1e5ecf303.diff LOG: Revert "[LLDB] XFAIL TestRunLocker.py on Windows" This reverts commit 9d28e00e741cb19684111656803434aceef4c2a0. Added: Modified: lldb/test/API/python_api/run_locker/TestRunLocker.py Removed: diff --git a/lldb/test/API/python_api/run_locker/TestRunLocker.py b/lldb/test/API/python_api/run_locker/TestRunLocker.py index ff34d47142b41..191400d6c024f 100644 --- a/lldb/test/API/python_api/run_locker/TestRunLocker.py +++ b/lldb/test/API/python_api/run_locker/TestRunLocker.py @@ -14,13 +14,11 @@ class TestRunLocker(TestBase): NO_DEBUG_INFO_TESTCASE = True -@expectedFailureAll(oslist=["windows"]) def test_run_locker(self): """Test that the run locker is set correctly when we launch""" self.build() self.runlocker_test(False) -@expectedFailureAll(oslist=["windows"]) def test_run_locker_stop_at_entry(self): """Test that the run locker is set correctly when we launch""" self.build() ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] e85e5ab - [LLDB] XFAIL TestRunLocker.py for windows
Author: Muhammad Omair Javaid Date: 2023-03-02T11:51:35+04:00 New Revision: e85e5abdceff6983a7ca1b647a97d0e0aaf6bf38 URL: https://github.com/llvm/llvm-project/commit/e85e5abdceff6983a7ca1b647a97d0e0aaf6bf38 DIFF: https://github.com/llvm/llvm-project/commit/e85e5abdceff6983a7ca1b647a97d0e0aaf6bf38.diff LOG: [LLDB] XFAIL TestRunLocker.py for windows TestRunLocker.py is failing on windows x64 and AArch64 buildbots. Buildbot log suggests that test needs some minor modification for windows which I will do later. https://lab.llvm.org/buildbot/#/builders/83/builds/29680 https://lab.llvm.org/buildbot/#/builders/219/builds/942 Added: Modified: lldb/test/API/python_api/run_locker/TestRunLocker.py Removed: diff --git a/lldb/test/API/python_api/run_locker/TestRunLocker.py b/lldb/test/API/python_api/run_locker/TestRunLocker.py index 191400d6c024f..c257684d22c24 100644 --- a/lldb/test/API/python_api/run_locker/TestRunLocker.py +++ b/lldb/test/API/python_api/run_locker/TestRunLocker.py @@ -7,6 +7,7 @@ import lldb import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * @@ -14,11 +15,13 @@ class TestRunLocker(TestBase): NO_DEBUG_INFO_TESTCASE = True +@expectedFailureAll(oslist=["windows"]) def test_run_locker(self): """Test that the run locker is set correctly when we launch""" self.build() self.runlocker_test(False) +@expectedFailureAll(oslist=["windows"]) def test_run_locker_stop_at_entry(self): """Test that the run locker is set correctly when we launch""" self.build() ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits