77 lines · python
1"""2Test that re-running a process from within the same target3after rebuilding the executable flushes the scratch TypeSystems4tied to that process.5"""6 7import lldb8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10from lldbsuite.test.decorators import *11 12 13class TestRerunExpr(TestBase):14 # FIXME: on Windows rebuilding the binary isn't enough to unload it15 # on progrem restart. One will have to try hard to evict16 # the module from the ModuleList (possibly including a call to17 # SBDebugger::MemoryPressureDetected.18 @skipIfWindows19 def test(self):20 """21 Tests whether re-launching a process without destroying22 the owning target keeps invalid ASTContexts in the23 scratch AST's importer.24 25 We test this by:26 1. Evaluating an expression to import 'struct Foo' into27 the scratch AST28 2. Change the definition of 'struct Foo' and rebuild the executable29 3. Re-launch the process30 4. Evaluate the same expression in (1). We expect to have only31 the latest definition of 'struct Foo' in the scratch AST.32 """33 self.build(dictionary={"CXX_SOURCES": "main.cpp", "EXE": "a.out"})34 35 exe = self.getBuildArtifact("a.out")36 target = self.dbg.CreateTarget(exe)37 target.BreakpointCreateBySourceRegex("return", lldb.SBFileSpec("rebuild.cpp"))38 target.BreakpointCreateBySourceRegex("return", lldb.SBFileSpec("main.cpp"))39 process = target.LaunchSimple(None, None, self.get_process_working_directory())40 41 self.expect_expr(42 "foo",43 result_type="Foo",44 result_children=[ValueCheck(name="m_val", value="42")],45 )46 47 # Delete the executable to force make to rebuild it.48 remove_file(exe)49 self.build(dictionary={"CXX_SOURCES": "rebuild.cpp", "EXE": "a.out"})50 51 # Rerun program within the same target52 process.Destroy()53 process = target.LaunchSimple(None, None, self.get_process_working_directory())54 55 self.expect_expr(56 "foo",57 result_type="Foo",58 result_children=[59 ValueCheck(60 name="Base", children=[ValueCheck(name="m_base_val", value="42")]61 ),62 ValueCheck(name="m_derived_val", value="137"),63 ],64 )65 66 self.filecheck("target module dump ast", __file__)67 68 # The new definition 'struct Foo' is in the scratch AST69 # CHECK: |-CXXRecordDecl {{.*}} struct Foo definition70 # CHECK: | |-public 'Base'71 # CHECK-NEXT: | `-FieldDecl {{.*}} m_derived_val 'int'72 # CHECK-NEXT: `-CXXRecordDecl {{.*}} struct Base definition73 # CHECK: `-FieldDecl {{.*}} m_base_val 'int'74 75 # ...but the original definition of 'struct Foo' is not in the scratch AST anymore76 # CHECK-NOT: FieldDecl {{.*}} m_val 'int'77