17e16571eSAdrian Vogelsgesangimport lldb 27e16571eSAdrian Vogelsgesangfrom lldbsuite.test.decorators import * 37e16571eSAdrian Vogelsgesangfrom lldbsuite.test.lldbtest import * 47e16571eSAdrian Vogelsgesangfrom lldbsuite.test import lldbutil 57e16571eSAdrian Vogelsgesang 6*2aed0d9cSAdrian Vogelsgesangimport re 77e16571eSAdrian Vogelsgesang 87e16571eSAdrian Vogelsgesangclass LibCxxInternalsRecognizerTestCase(TestBase): 97e16571eSAdrian Vogelsgesang NO_DEBUG_INFO_TESTCASE = True 107e16571eSAdrian Vogelsgesang 117e16571eSAdrian Vogelsgesang @add_test_categories(["libc++"]) 12*2aed0d9cSAdrian Vogelsgesang @skipIf(compiler="clang", compiler_version=["<", "16.0"]) 137e16571eSAdrian Vogelsgesang def test_frame_recognizer(self): 147e16571eSAdrian Vogelsgesang """Test that implementation details of libc++ are hidden""" 157e16571eSAdrian Vogelsgesang self.build() 167e16571eSAdrian Vogelsgesang (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( 177e16571eSAdrian Vogelsgesang self, "break here", lldb.SBFileSpec("main.cpp") 187e16571eSAdrian Vogelsgesang ) 197e16571eSAdrian Vogelsgesang 207e16571eSAdrian Vogelsgesang expected_parents = { 217e16571eSAdrian Vogelsgesang "sort_less(int, int)": ["::sort", "test_algorithms"], 227e16571eSAdrian Vogelsgesang # `std::ranges::sort` is implemented as an object of types `__sort`. 237e16571eSAdrian Vogelsgesang # We never hide the frame of the entry-point into the standard library, even 247e16571eSAdrian Vogelsgesang # if the name starts with `__` which usually indicates an internal function. 257e16571eSAdrian Vogelsgesang "ranges_sort_less(int, int)": [ 26*2aed0d9cSAdrian Vogelsgesang re.compile("ranges::__sort::(__fn::)?operator\(\)"), 277e16571eSAdrian Vogelsgesang "test_algorithms", 287e16571eSAdrian Vogelsgesang ], 297e16571eSAdrian Vogelsgesang # `ranges::views::transform` internally uses `std::invoke`, and that 307e16571eSAdrian Vogelsgesang # call also shows up in the stack trace 317e16571eSAdrian Vogelsgesang "view_transform(int)": [ 327e16571eSAdrian Vogelsgesang "::invoke", 337e16571eSAdrian Vogelsgesang "ranges::transform_view", 347e16571eSAdrian Vogelsgesang "test_algorithms", 357e16571eSAdrian Vogelsgesang ], 367e16571eSAdrian Vogelsgesang # Various types of `invoke` calls 377e16571eSAdrian Vogelsgesang "consume_number(int)": ["::invoke", "test_invoke"], 387e16571eSAdrian Vogelsgesang "invoke_add(int, int)": ["::invoke", "test_invoke"], 397e16571eSAdrian Vogelsgesang "Callable::member_function(int) const": ["::invoke", "test_invoke"], 407e16571eSAdrian Vogelsgesang "Callable::operator()(int) const": ["::invoke", "test_invoke"], 417e16571eSAdrian Vogelsgesang # Containers 427e16571eSAdrian Vogelsgesang "MyKey::operator<(MyKey const&) const": [ 437e16571eSAdrian Vogelsgesang "less", 447e16571eSAdrian Vogelsgesang "::emplace", 457e16571eSAdrian Vogelsgesang "test_containers", 467e16571eSAdrian Vogelsgesang ], 477e16571eSAdrian Vogelsgesang } 487e16571eSAdrian Vogelsgesang stop_set = set() 497e16571eSAdrian Vogelsgesang while process.GetState() != lldb.eStateExited: 507e16571eSAdrian Vogelsgesang fn = thread.GetFrameAtIndex(0).GetFunctionName() 517e16571eSAdrian Vogelsgesang stop_set.add(fn) 527e16571eSAdrian Vogelsgesang self.assertIn(fn, expected_parents.keys()) 537e16571eSAdrian Vogelsgesang frame_id = 1 547e16571eSAdrian Vogelsgesang for expected_parent in expected_parents[fn]: 557e16571eSAdrian Vogelsgesang # Skip all hidden frames 567e16571eSAdrian Vogelsgesang while ( 577e16571eSAdrian Vogelsgesang frame_id < thread.GetNumFrames() 587e16571eSAdrian Vogelsgesang and thread.GetFrameAtIndex(frame_id).IsHidden() 597e16571eSAdrian Vogelsgesang ): 607e16571eSAdrian Vogelsgesang frame_id = frame_id + 1 617e16571eSAdrian Vogelsgesang # Expect the correct parent frame 62*2aed0d9cSAdrian Vogelsgesang func_name = thread.GetFrameAtIndex(frame_id).GetFunctionName() 63*2aed0d9cSAdrian Vogelsgesang if isinstance(expected_parent, re.Pattern): 64*2aed0d9cSAdrian Vogelsgesang self.assertTrue( 65*2aed0d9cSAdrian Vogelsgesang expected_parent.search(func_name) is not None, 66*2aed0d9cSAdrian Vogelsgesang f"'{expected_parent}' not found in '{func_name}'" 677e16571eSAdrian Vogelsgesang ) 68*2aed0d9cSAdrian Vogelsgesang else: 69*2aed0d9cSAdrian Vogelsgesang self.assertIn(expected_parent, func_name) 707e16571eSAdrian Vogelsgesang frame_id = frame_id + 1 717e16571eSAdrian Vogelsgesang process.Continue() 727e16571eSAdrian Vogelsgesang 737e16571eSAdrian Vogelsgesang # Make sure that we actually verified all intended scenarios 747e16571eSAdrian Vogelsgesang self.assertEqual(len(stop_set), len(expected_parents)) 75