xref: /llvm-project/lldb/test/API/functionalities/rerun_and_expr/TestRerunAndExpr.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1e1edcf7dSMichael Buch"""
2e1edcf7dSMichael BuchTest that re-running a process from within the same target
3e1edcf7dSMichael Buchafter rebuilding the executable flushes the scratch TypeSystems
4e1edcf7dSMichael Buchtied to that process.
5e1edcf7dSMichael Buch"""
6e1edcf7dSMichael Buch
7e1edcf7dSMichael Buchimport lldb
8e1edcf7dSMichael Buchfrom lldbsuite.test.lldbtest import *
9e1edcf7dSMichael Buchfrom lldbsuite.test import lldbutil
10a2200263SMichael Buchfrom lldbsuite.test.decorators import *
11e1edcf7dSMichael Buch
12*2238dcc3SJonas Devlieghere
13e1edcf7dSMichael Buchclass TestRerunExpr(TestBase):
14a2200263SMichael Buch    # FIXME: on Windows rebuilding the binary isn't enough to unload it
15a2200263SMichael Buch    #        on progrem restart. One will have to try hard to evict
16a2200263SMichael Buch    #        the module from the ModuleList (possibly including a call to
17a2200263SMichael Buch    #        SBDebugger::MemoryPressureDetected.
18a2200263SMichael Buch    @skipIfWindows
19e1edcf7dSMichael Buch    def test(self):
20e1edcf7dSMichael Buch        """
21e1edcf7dSMichael Buch        Tests whether re-launching a process without destroying
22e1edcf7dSMichael Buch        the owning target keeps invalid ASTContexts in the
23e1edcf7dSMichael Buch        scratch AST's importer.
24e1edcf7dSMichael Buch
25e1edcf7dSMichael Buch        We test this by:
26e1edcf7dSMichael Buch        1. Evaluating an expression to import 'struct Foo' into
27e1edcf7dSMichael Buch           the scratch AST
28e1edcf7dSMichael Buch        2. Change the definition of 'struct Foo' and rebuild the executable
29e1edcf7dSMichael Buch        3. Re-launch the process
30e1edcf7dSMichael Buch        4. Evaluate the same expression in (1). We expect to have only
31e1edcf7dSMichael Buch           the latest definition of 'struct Foo' in the scratch AST.
32e1edcf7dSMichael Buch        """
33*2238dcc3SJonas Devlieghere        self.build(dictionary={"CXX_SOURCES": "main.cpp", "EXE": "a.out"})
34e1edcf7dSMichael Buch
35e1edcf7dSMichael Buch        exe = self.getBuildArtifact("a.out")
36e1edcf7dSMichael Buch        target = self.dbg.CreateTarget(exe)
37*2238dcc3SJonas Devlieghere        target.BreakpointCreateBySourceRegex("return", lldb.SBFileSpec("rebuild.cpp"))
38*2238dcc3SJonas Devlieghere        target.BreakpointCreateBySourceRegex("return", lldb.SBFileSpec("main.cpp"))
39e1edcf7dSMichael Buch        process = target.LaunchSimple(None, None, self.get_process_working_directory())
40e1edcf7dSMichael Buch
41*2238dcc3SJonas Devlieghere        self.expect_expr(
42*2238dcc3SJonas Devlieghere            "foo",
43*2238dcc3SJonas Devlieghere            result_type="Foo",
44*2238dcc3SJonas Devlieghere            result_children=[ValueCheck(name="m_val", value="42")],
45*2238dcc3SJonas Devlieghere        )
46e1edcf7dSMichael Buch
47ad3870d6SMichael Buch        # Delete the executable to force make to rebuild it.
48ad3870d6SMichael Buch        remove_file(exe)
49*2238dcc3SJonas Devlieghere        self.build(dictionary={"CXX_SOURCES": "rebuild.cpp", "EXE": "a.out"})
50e1edcf7dSMichael Buch
51e1edcf7dSMichael Buch        # Rerun program within the same target
52e1edcf7dSMichael Buch        process.Destroy()
53e1edcf7dSMichael Buch        process = target.LaunchSimple(None, None, self.get_process_working_directory())
54e1edcf7dSMichael Buch
55*2238dcc3SJonas Devlieghere        self.expect_expr(
56*2238dcc3SJonas Devlieghere            "foo",
57*2238dcc3SJonas Devlieghere            result_type="Foo",
58*2238dcc3SJonas Devlieghere            result_children=[
59*2238dcc3SJonas Devlieghere                ValueCheck(
60*2238dcc3SJonas Devlieghere                    name="Base", children=[ValueCheck(name="m_base_val", value="42")]
61*2238dcc3SJonas Devlieghere                ),
62*2238dcc3SJonas Devlieghere                ValueCheck(name="m_derived_val", value="137"),
63*2238dcc3SJonas Devlieghere            ],
64*2238dcc3SJonas Devlieghere        )
65e1edcf7dSMichael Buch
66e1edcf7dSMichael Buch        self.filecheck("target module dump ast", __file__)
67e1edcf7dSMichael Buch
68e1edcf7dSMichael Buch        # The new definition 'struct Foo' is in the scratch AST
69e1edcf7dSMichael Buch        # CHECK:      |-CXXRecordDecl {{.*}} struct Foo definition
70e1edcf7dSMichael Buch        # CHECK:      | |-public 'Base'
71e1edcf7dSMichael Buch        # CHECK-NEXT: | `-FieldDecl {{.*}} m_derived_val 'int'
72e1edcf7dSMichael Buch        # CHECK-NEXT: `-CXXRecordDecl {{.*}} struct Base definition
73e1edcf7dSMichael Buch        # CHECK:        `-FieldDecl {{.*}} m_base_val 'int'
74e1edcf7dSMichael Buch
75e1edcf7dSMichael Buch        # ...but the original definition of 'struct Foo' is not in the scratch AST anymore
76e1edcf7dSMichael Buch        # CHECK-NOT: FieldDecl {{.*}} m_val 'int'
77