[Lldb-commits] [PATCH] D129528: Modify all register values whose byte size matches the address size to be formatter as eFormatAddressInfo.

Greg Clayton via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Mon Jul 11 17:53:37 PDT 2022


clayborg created this revision.
clayborg added reviewers: labath, JDevlieghere, jingham, aadsm, yinghuitan.
Herald added a project: All.
clayborg requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

This allows users to see similar output to what the "register read" command emits in LLDB's command line.

Added a test to verify that the PC has the correct value with contains a pointer followed by the module + function name and the source line info. Something like:

0x0000000100000a64 a.out`main + 132 at main.cpp:17:11


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D129528

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/variables/TestVSCode_variables.py
  lldb/tools/lldb-vscode/lldb-vscode.cpp


Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===================================================================
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1932,6 +1932,22 @@
                                                /*statics=*/true,
                                                /*in_scope_only=*/true);
   g_vsc.variables.registers = frame.GetRegisters();
+
+  // Change the default format of any pointer sized registers to be the
+  // lldb::eFormatAddressInfo so we show the pointer and resolve what the
+  // pointer resolves to.
+  uint32_t addr_size = frame.GetThread().GetProcess().GetAddressByteSize();
+  const uint32_t num_reg_sets = g_vsc.variables.registers.GetSize();
+  for (uint32_t reg_set_idx=0; reg_set_idx<num_reg_sets; ++reg_set_idx) {
+    lldb::SBValue reg_set =
+        g_vsc.variables.registers.GetValueAtIndex(reg_set_idx);
+    const uint32_t num_regs = reg_set.GetNumChildren();
+    for (uint32_t reg_idx=0; reg_idx<num_regs; ++reg_idx) {
+      lldb::SBValue reg = reg_set.GetChildAtIndex(reg_idx);
+      if (reg.GetByteSize() == addr_size)
+        reg.SetFormat(lldb::eFormatAddressInfo);
+    }
+  }
   body.try_emplace("scopes", g_vsc.CreateTopLevelScopes());
   response.try_emplace("body", std::move(body));
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
Index: lldb/test/API/tools/lldb-vscode/variables/TestVSCode_variables.py
===================================================================
--- lldb/test/API/tools/lldb-vscode/variables/TestVSCode_variables.py
+++ lldb/test/API/tools/lldb-vscode/variables/TestVSCode_variables.py
@@ -462,3 +462,52 @@
             "pt": {"missing": ["indexedVariables"]},
         }
         self.verify_variables(verify_locals, locals)
+
+    @skipIfWindows
+    @skipIfRemote
+    def test_registers(self):
+        '''
+            Test that registers whose byte size is the size of a pointer on
+            the current system get formatted as lldb::eFormatAddressInfo. This
+            will show the pointer value followed by a description of the address
+            itself. To test this we attempt to find the PC value in the general
+            purpose registers, and since we will be stopped in main.cpp, verify
+            that the value for the PC starts with a pointer and is followed by
+            a description that contains main.cpp.
+        '''
+        program = self.getBuildArtifact("a.out")
+        self.build_and_launch(program)
+        source = "main.cpp"
+        breakpoint1_line = line_number(source, "// breakpoint 1")
+        lines = [breakpoint1_line]
+        # Set breakpoint in the thread function so we can step the threads
+        breakpoint_ids = self.set_source_breakpoints(source, lines)
+        self.assertEqual(
+            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
+        )
+        self.continue_to_breakpoints(breakpoint_ids)
+
+
+        pc_name = None
+        arch = self.getArchitecture()
+        if arch == 'x86_64':
+            pc_name = 'rip'
+        elif arch == 'x86':
+            pc_name = 'rip'
+        elif arch.startswith('arm'):
+            pc_name = 'pc'
+
+        if pc_name is None:
+            return
+        # Verify locals
+        reg_sets = self.vscode.get_registers()
+        for reg_set in reg_sets:
+            if reg_set['name'] == 'General Purpose Registers':
+                varRef = reg_set['variablesReference']
+                regs = self.vscode.request_variables(varRef)['body']['variables']
+                for reg in regs:
+                    if reg['name'] == pc_name:
+                        value = reg['value']
+                        self.assertTrue(value.startswith('0x'))
+                        self.assertTrue('a.out`main + ' in value)
+                        self.assertTrue('at main.cpp:' in value)
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
@@ -447,6 +447,10 @@
         return self.get_scope_variables('Locals', frameIndex=frameIndex,
                                         threadId=threadId)
 
+    def get_registers(self, frameIndex=0, threadId=None):
+        return self.get_scope_variables('Registers', frameIndex=frameIndex,
+                                        threadId=threadId)
+
     def get_local_variable(self, name, frameIndex=0, threadId=None):
         locals = self.get_local_variables(frameIndex=frameIndex,
                                           threadId=threadId)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D129528.443803.patch
Type: text/x-patch
Size: 4722 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20220712/70944540/attachment.bin>


More information about the lldb-commits mailing list