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)
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)
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits