llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: David Spickett (DavidSpickett) <details> <summary>Changes</summary> Follow up to #<!-- -->218819. It was agreed in https://discourse.llvm.org/t/running-lldb-in-a-container/76801/1 that we would default to ALSR being on during the test suite. This means people don't have to reconfigure their systems to run our tests out of the box. So we need to look before we run a test that needs to disable ASLR. Here I am adding a decorator to do that. It assumes it's always allowed on MacOS and uses personality (https://man7.org/linux/man-pages/man2/personality.2.html) to check if we can change it on Linux. Since we're calling personality on the test process, this cannot be done for a remote target. We could go launch a process but for the added complexity I didn't think the extra coverage was worth it. So "Not able to disable ASLR" is a bit of a simplification because sometimes we might be able to but didn't check. --- Full diff: https://github.com/llvm/llvm-project/pull/218883.diff 5 Files Affected: - (modified) lldb/packages/Python/lldbsuite/test/decorators.py (+40) - (modified) lldb/source/Breakpoint/Watchpoint.cpp (+5) - (added) lldb/test/API/functionalities/watchpoint/run-reenable-watchpoint/Makefile (+3) - (added) lldb/test/API/functionalities/watchpoint/run-reenable-watchpoint/TestRunReEnableWatchpoint.py (+51) - (added) lldb/test/API/functionalities/watchpoint/run-reenable-watchpoint/main.c (+6) ``````````diff diff --git a/lldb/packages/Python/lldbsuite/test/decorators.py b/lldb/packages/Python/lldbsuite/test/decorators.py index 306eb20622746..6c02b56d2645f 100644 --- a/lldb/packages/Python/lldbsuite/test/decorators.py +++ b/lldb/packages/Python/lldbsuite/test/decorators.py @@ -1289,6 +1289,46 @@ def requireThreadSupport(func): )(func) +def _can_disable_aslr(): + original_persona = None + GET_CURRENT_PERSONA = 0xFFFFFFFF + ADDR_NO_RANDOMIZE = 0x0040000 + ERR = -1 + + libc = ctypes.CDLL(None) + personality = libc.personality + personality.argtypes = [ctypes.c_ulong] + personality.restype = ctypes.c_int + + try: + original_persona = personality(GET_CURRENT_PERSONA) + if original_persona == ERR: + return False + + if personality(original_persona | ADDR_NO_RANDOMIZE) == ERR: + return False + + new_persona = personality(GET_CURRENT_PERSONA) + if new_persona == ERR: + return False + + return new_persona & ADDR_NO_RANDOMIZE + finally: + if original_persona is not None: + personality(original_persona) + + +def requireDisableASLR(func): + platform = lldbplatformutil.getPlatform() + return unittest.skipIf( + platform != "macosx" + and not ( + lldb.remote_platform is None and platform == "linux" and _can_disable_aslr() + ), + UnsupportedReason(f"Not able to disable ASLR"), + )(func) + + def skipIfTargetDoesNotSupportSharedLibraries(): """Skip tests that require shared library (dylib/so) support.""" platform = lldbplatformutil.getPlatform() diff --git a/lldb/source/Breakpoint/Watchpoint.cpp b/lldb/source/Breakpoint/Watchpoint.cpp index e839c8b9f30e7..13bc2556a9b9c 100644 --- a/lldb/source/Breakpoint/Watchpoint.cpp +++ b/lldb/source/Breakpoint/Watchpoint.cpp @@ -421,6 +421,11 @@ void Watchpoint::SetEnabled(bool enabled, bool notify) { } bool changed = enabled != m_enabled; m_enabled = enabled; + if (enabled && !m_new_value_sp && m_target.GetProcessSP()) { + ExecutionContext exe_ctx; + m_target.GetProcessSP()->CalculateExecutionContext(exe_ctx); + CaptureWatchedValue(exe_ctx); + } if (notify && !m_is_ephemeral && changed) SendWatchpointChangedEvent(enabled ? eWatchpointEventTypeEnabled : eWatchpointEventTypeDisabled); diff --git a/lldb/test/API/functionalities/watchpoint/run-reenable-watchpoint/Makefile b/lldb/test/API/functionalities/watchpoint/run-reenable-watchpoint/Makefile new file mode 100644 index 0000000000000..10495940055b6 --- /dev/null +++ b/lldb/test/API/functionalities/watchpoint/run-reenable-watchpoint/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/functionalities/watchpoint/run-reenable-watchpoint/TestRunReEnableWatchpoint.py b/lldb/test/API/functionalities/watchpoint/run-reenable-watchpoint/TestRunReEnableWatchpoint.py new file mode 100644 index 0000000000000..6b18e460dcb99 --- /dev/null +++ b/lldb/test/API/functionalities/watchpoint/run-reenable-watchpoint/TestRunReEnableWatchpoint.py @@ -0,0 +1,51 @@ +""" +Test that a watchpoint created in one Process can be +re-enabled in a second Process launch and behave +correctly. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class RunReEnableWatchpointTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + def continue_and_report_stop_reason(self, process, iter_str): + process.Continue() + self.assertIn( + process.GetState(), [lldb.eStateStopped, lldb.eStateExited], iter_str + ) + thread = process.GetSelectedThread() + return thread.GetStopReason() + + # We must be able to launch the inferior with ASLR disabled + # so the static array lands at the same address after relaunch. + @requireDisableASLR + def test_rerun_enable_watchpoint(self): + """Test set watchpoint, re-run, re-enable wp, hit it.""" + self.build() + self.main_source_file = lldb.SBFileSpec("main.c") + li = lldb.SBLaunchInfo(None) + li.SetLaunchFlags(lldb.eLaunchFlagDisableASLR) + target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, "break here", self.main_source_file, launch_info=li + ) + + frame = thread.GetFrameAtIndex(0) + self.runCmd("watch set variable arr") + + reason = self.continue_and_report_stop_reason(process, "continue first-launch") + self.assertEqual(reason, lldb.eStopReasonWatchpoint) + + process.Kill() + self.runCmd("process launch --disable-aslr true") + process = target.GetProcess() + self.assertTrue(process.IsValid()) + + target.EnableAllWatchpoints() + + reason = self.continue_and_report_stop_reason(process, "continue second-launch") + self.assertEqual(reason, lldb.eStopReasonWatchpoint) diff --git a/lldb/test/API/functionalities/watchpoint/run-reenable-watchpoint/main.c b/lldb/test/API/functionalities/watchpoint/run-reenable-watchpoint/main.c new file mode 100644 index 0000000000000..0969dd247bf74 --- /dev/null +++ b/lldb/test/API/functionalities/watchpoint/run-reenable-watchpoint/main.c @@ -0,0 +1,6 @@ +static int arr[] = {1, 2, 0, 3, 4, 0x55555555}; +int main() { + arr[0]++; // break here + arr[0]++; + return arr[4]; +} `````````` </details> https://github.com/llvm/llvm-project/pull/218883 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
