| """ |
| Use lldb Python SBBlock API to access specific scopes within a frame. |
| """ |
| |
| import lldb |
| from lldbsuite.test.decorators import * |
| from lldbsuite.test.lldbtest import * |
| from lldbsuite.test import lldbutil |
| |
| |
| class FrameBlocksTestCase(TestBase): |
| @skipIfWindows |
| def test_block_equality(self): |
| """Exercise SBBlock equality checks across frames and functions in different dylibs.""" |
| self.build() |
| target, process, thread, _ = lldbutil.run_to_source_breakpoint( |
| self, "// breakpoint 1", lldb.SBFileSpec("main.c"), extra_images=["libfn"] |
| ) |
| |
| frame = thread.GetFrameAtIndex(0) |
| self.assertTrue(frame.IsValid(), "Frame must be valid") |
| |
| main_frame_block = frame.GetFrameBlock() |
| |
| threads = lldbutil.continue_to_source_breakpoint( |
| self, |
| process, |
| "// breakpoint 2", |
| lldb.SBFileSpec("fn.c"), |
| ) |
| self.assertEqual( |
| len(threads), 1, "There should be a thread stopped at breakpoint 2" |
| ) |
| |
| thread = threads[0] |
| self.assertTrue(thread.IsValid(), "Thread must be valid") |
| frame = thread.GetFrameAtIndex(0) |
| self.assertTrue(frame.IsValid(), "Frame must be valid") |
| |
| fn_frame_block = frame.GetFrameBlock() |
| fn_inner_block = frame.GetBlock() |
| |
| # Check __eq__ / __ne__ |
| self.assertNotEqual(lldb.SBBlock(), lldb.SBBlock()) |
| self.assertNotEqual(fn_inner_block, fn_frame_block) |
| self.assertNotEqual(main_frame_block, fn_frame_block) |
| self.assertEqual(fn_inner_block.GetParent(), fn_frame_block) |
| self.assertEqual(fn_frame_block.GetFirstChild(), fn_inner_block) |
| |
| # Load the main function with a different API to ensure we have two |
| # distinct SBBlock objects. |
| main_func_list = target.FindModule(target.GetExecutable()).FindFunctions("main") |
| self.assertEqual(main_func_list.GetSize(), 1) |
| main_func = main_func_list.GetContextAtIndex(0).GetFunction() |
| self.assertIsNotNone(main_func) |
| |
| # Ensure they we have two distinct objects that represent the same block |
| main_func_block = main_func.GetBlock() |
| self.assertIsNot(main_func_block, main_frame_block) |
| self.assertEqual(main_func_block, main_frame_block) |