brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · 82ff59f Raw
196 lines · python
1"""2Test dwim-print with variables, variable paths, and expressions.3"""4 5import re6import lldb7from lldbsuite.test.lldbtest import *8from lldbsuite.test.decorators import *9import lldbsuite.test.lldbutil as lldbutil10 11 12class TestCase(TestBase):13    def _run_cmd(self, cmd: str) -> str:14        """Run the given lldb command and return its output."""15        result = lldb.SBCommandReturnObject()16        self.ci.HandleCommand(cmd, result)17        return result.GetOutput().rstrip()18 19    VAR_IDENT = re.compile(r"(?:\$\d+|(?:::)?[\w.]+) = ")20 21    def _strip_result_var(self, string: str) -> str:22        """23        Strip (persistent) result variables (ex '$0 = ', or 'someVar = ', etc).24 25        This allows for using the output of `expression`/`frame variable`, to26        compare it to `dwim-print` output, which disables result variables.27        """28        return self.VAR_IDENT.subn("", string, 1)[0]29 30    def _expect_cmd(31        self,32        dwim_cmd: str,33        actual_cmd: str,34    ) -> None:35        """Run dwim-print and verify the output against the expected command."""36        # Resolve the dwim-print command to either `expression` or `frame variable`.37        substitute_cmd = dwim_cmd.replace("dwim-print", actual_cmd, 1)38        interp = self.dbg.GetCommandInterpreter()39        result = lldb.SBCommandReturnObject()40        interp.ResolveCommand(substitute_cmd, result)41        self.assertTrue(result.Succeeded(), result.GetError())42 43        resolved_cmd = result.GetOutput()44        if actual_cmd == "frame variable":45            resolved_cmd = resolved_cmd.replace(" -- ", " ", 1)46 47        resolved_cmd_output = self._run_cmd(resolved_cmd)48        dwim_cmd_output = self._strip_result_var(resolved_cmd_output)49 50        # Verify dwim-print chose the expected command.51        self.runCmd("settings set dwim-print-verbosity full")52 53        self.expect(54            dwim_cmd,55            substrs=[56                f"note: ran `{resolved_cmd}`",57                dwim_cmd_output,58            ],59        )60 61    def test_variables(self):62        """Test dwim-print with variables."""63        self.build()64        lldbutil.run_to_name_breakpoint(self, "main")65        vars = ("argc", "argv")66        for var in vars:67            self._expect_cmd(f"dwim-print {var}", "frame variable")68 69    def test_variable_paths(self):70        """Test dwim-print with variable path expressions."""71        self.build()72        lldbutil.run_to_name_breakpoint(self, "main")73        exprs = ("&argc", "*argv", "argv[0]")74        for expr in exprs:75            self._expect_cmd(f"dwim-print {expr}", "expression")76 77    def test_expressions(self):78        """Test dwim-print with expressions."""79        self.build()80        lldbutil.run_to_name_breakpoint(self, "main")81        exprs = ("argc + 1", "(void)argc", "(int)abs(argc)")82        for expr in exprs:83            self._expect_cmd(f"dwim-print {expr}", "expression")84 85    def test_dummy_target_expressions(self):86        """Test dwim-print's ability to evaluate expressions without a target."""87        self._expect_cmd("dwim-print 1 + 2", "expression")88 89    def test_gdb_format(self):90        self.build()91        lldbutil.run_to_name_breakpoint(self, "main")92        self._expect_cmd(f"dwim-print/x argc", "frame variable")93        self._expect_cmd(f"dwim-print/x argc + 1", "expression")94 95    def test_format_flags(self):96        self.build()97        lldbutil.run_to_name_breakpoint(self, "main")98        self._expect_cmd(f"dwim-print -fx -- argc", "frame variable")99        self._expect_cmd(f"dwim-print -fx -- argc + 1", "expression")100 101    def test_display_flags(self):102        self.build()103        lldbutil.run_to_name_breakpoint(self, "main")104        self._expect_cmd(f"dwim-print -T -- argc", "frame variable")105        self._expect_cmd(f"dwim-print -T -- argc + 1", "expression")106 107    def test_expression_language(self):108        """Test that the language flag doesn't affect the choice of command."""109        self.build()110        lldbutil.run_to_name_breakpoint(self, "main")111        self._expect_cmd(f"dwim-print -l c++ -- argc", "frame variable")112        self._expect_cmd(f"dwim-print -l c++ -- argc + 1", "expression")113 114    def test_empty_expression(self):115        self.build()116        lldbutil.run_to_name_breakpoint(self, "main")117        error_msg = "error: 'dwim-print' takes a variable or expression"118        self.expect(f"dwim-print", error=True, startstr=error_msg)119        self.expect(f"dwim-print -- ", error=True, startstr=error_msg)120 121    def test_nested_values(self):122        """Test dwim-print with nested values (structs, etc)."""123        self.build()124        lldbutil.run_to_source_breakpoint(125            self, "break here", lldb.SBFileSpec("main.cpp")126        )127        self.runCmd("settings set auto-one-line-summaries false")128        self._expect_cmd(f"dwim-print s", "frame variable")129        self._expect_cmd(f"dwim-print (struct Structure)s", "expression")130 131    def test_summary_strings(self):132        """Test dwim-print with type summaries."""133        self.build()134        lldbutil.run_to_source_breakpoint(135            self, "break here", lldb.SBFileSpec("main.cpp")136        )137        self.runCmd("settings set auto-one-line-summaries false")138        self.runCmd("type summary add -e -s 'stub summary' Structure")139        self._expect_cmd(f"dwim-print s", "frame variable")140        self._expect_cmd(f"dwim-print (struct Structure)s", "expression")141        self.runCmd("type summary delete Structure")142 143    def test_void_result(self):144        """Test dwim-print does not surface an error message for void expressions."""145        self.build()146        lldbutil.run_to_source_breakpoint(147            self, "break here", lldb.SBFileSpec("main.cpp")148        )149        self.expect("dwim-print (void)15", matching=False, patterns=["(?i)error"])150 151    def test_preserves_persistent_variables(self):152        """Test dwim-print does not delete persistent variables."""153        self.build()154        lldbutil.run_to_source_breakpoint(155            self, "break here", lldb.SBFileSpec("main.cpp")156        )157        self.expect("dwim-print int $i = 15")158        # Run the same expression twice and verify success. This ensures the159        # first command does not delete the persistent variable.160        for _ in range(2):161            self.expect("dwim-print $i", startstr="(int) 15")162 163    def test_missing_type(self):164        """The expected output of po opaque is its address (no error)"""165        self.build()166        lldbutil.run_to_source_breakpoint(167            self, "break here", lldb.SBFileSpec("main.cpp")168        )169        self.expect("dwim-print -O -- opaque", substrs=["0x"])170 171    def test_variable_expression_path(self):172        """Test dwim-print supports certain variable expression paths."""173        self.build()174        lldbutil.run_to_source_breakpoint(175            self, "break here", lldb.SBFileSpec("main.cpp")176        )177        self.runCmd("settings set auto-one-line-summaries false")178        self._expect_cmd("dwim-print w.s", "frame variable")179        self._expect_cmd("dwim-print wp->s", "expression")180 181    def test_direct_child_access(self):182        """Test dwim-print supports accessing members/ivars without qualification."""183        self.build()184        lldbutil.run_to_source_breakpoint(185            self, "break inside", lldb.SBFileSpec("main.cpp")186        )187        self._expect_cmd("dwim-print number", "frame variable")188 189    def test_global_variables(self):190        """Test dwim-print supports global variables."""191        self.build()192        lldbutil.run_to_source_breakpoint(193            self, "break here", lldb.SBFileSpec("main.cpp")194        )195        self._expect_cmd("dwim-print gGlobal", "frame variable")196