[lldb-vscode] Add an option for loading core files
authorWalter Erquinigo <waltermelon@fb.com>
Fri, 24 Apr 2020 23:35:57 +0000 (16:35 -0700)
committerWalter Erquinigo <waltermelon@fb.com>
Tue, 28 Apr 2020 20:03:02 +0000 (13:03 -0700)
Summary:
Currently loading core files on lldb-vscode is broken because there's a check in the attach workflow that asserts that the PID is valid, which of course fails for this case.
Hence, I'm adding a "coreFile" argument for the attach request, which does the work correctly.

I don't know how to test it effectively so that it runs on the buildbots and the debugger can in fact makes sense of it. Anyway, the change has been relatively simple.

Reviewers: labath, clayborg

Subscribers: lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D78839

lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
lldb/test/API/tools/lldb-vscode/coreFile/TestVSCode_coreFile.py [new file with mode: 0644]
lldb/test/API/tools/lldb-vscode/coreFile/linux-x86_64.core [new file with mode: 0644]
lldb/test/API/tools/lldb-vscode/coreFile/linux-x86_64.out [new file with mode: 0755]
lldb/tools/lldb-vscode/README.md
lldb/tools/lldb-vscode/lldb-vscode.cpp
lldb/tools/lldb-vscode/package.json

index 3b06fa0..790628d 100644 (file)
@@ -239,7 +239,7 @@ class VSCodeTestCaseBase(TestBase):
 
     def attach(self, program=None, pid=None, waitFor=None, trace=None,
                initCommands=None, preRunCommands=None, stopCommands=None,
-               exitCommands=None, attachCommands=None):
+               exitCommands=None, attachCommands=None, coreFile=None):
         '''Build the default Makefile target, create the VSCode debug adaptor,
            and attach to the process.
         '''
@@ -257,7 +257,7 @@ class VSCodeTestCaseBase(TestBase):
             program=program, pid=pid, waitFor=waitFor, trace=trace,
             initCommands=initCommands, preRunCommands=preRunCommands,
             stopCommands=stopCommands, exitCommands=exitCommands,
-            attachCommands=attachCommands)
+            attachCommands=attachCommands, coreFile=coreFile)
         if not (response and response['success']):
             self.assertTrue(response['success'],
                             'attach failed (%s)' % (response['message']))
index 805de43..643a313 100644 (file)
@@ -450,7 +450,7 @@ class DebugCommunication(object):
     def request_attach(self, program=None, pid=None, waitFor=None, trace=None,
                        initCommands=None, preRunCommands=None,
                        stopCommands=None, exitCommands=None,
-                       attachCommands=None):
+                       attachCommands=None, coreFile=None):
         args_dict = {}
         if pid is not None:
             args_dict['pid'] = pid
@@ -471,6 +471,8 @@ class DebugCommunication(object):
             args_dict['exitCommands'] = exitCommands
         if attachCommands:
             args_dict['attachCommands'] = attachCommands
+        if coreFile:
+            args_dict['coreFile'] = coreFile
         command_dict = {
             'command': 'attach',
             'type': 'request',
diff --git a/lldb/test/API/tools/lldb-vscode/coreFile/TestVSCode_coreFile.py b/lldb/test/API/tools/lldb-vscode/coreFile/TestVSCode_coreFile.py
new file mode 100644 (file)
index 0000000..55efd91
--- /dev/null
@@ -0,0 +1,43 @@
+"""
+Test lldb-vscode coreFile attaching
+"""
+
+
+import unittest2
+import vscode
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbvscode_testcase
+import os
+
+
+class TestVSCode_coreFile(lldbvscode_testcase.VSCodeTestCaseBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipIfWindows
+    @skipIfRemote
+    @skipIfLLVMTargetMissing("X86")
+    def test_core_file(self):
+        current_dir = os.path.dirname(os.path.realpath(__file__))
+        exe_file = os.path.join(current_dir, "linux-x86_64.out")
+        core_file = os.path.join(current_dir, "linux-x86_64.core")
+
+        self.create_debug_adaptor()
+        self.attach(exe_file, coreFile=core_file)
+
+        expected_frames = [
+            {'column': 0, 'id': 524288, 'line': 4, 'name': 'bar', 'source': {'name': 'main.c', 'path': '/home/labath/test/main.c'}},
+            {'column': 0, 'id': 524289, 'line': 10, 'name': 'foo', 'source': {'name': 'main.c', 'path': '/home/labath/test/main.c'}},
+            {'column': 0, 'id': 524290, 'line': 16, 'name': '_start', 'source': {'name': 'main.c', 'path': '/home/labath/test/main.c'}},
+        ]
+
+        self.assertEquals(self.get_stackFrames(), expected_frames)
+
+        # Resuming should have no effect and keep the process stopped
+        self.continue_to_next_stop()
+        self.assertEquals(self.get_stackFrames(), expected_frames)
+
+        self.vscode.request_next(threadId=32259)
+        self.assertEquals(self.get_stackFrames(), expected_frames)
diff --git a/lldb/test/API/tools/lldb-vscode/coreFile/linux-x86_64.core b/lldb/test/API/tools/lldb-vscode/coreFile/linux-x86_64.core
new file mode 100644 (file)
index 0000000..2675ead
Binary files /dev/null and b/lldb/test/API/tools/lldb-vscode/coreFile/linux-x86_64.core differ
diff --git a/lldb/test/API/tools/lldb-vscode/coreFile/linux-x86_64.out b/lldb/test/API/tools/lldb-vscode/coreFile/linux-x86_64.out
new file mode 100755 (executable)
index 0000000..842402f
Binary files /dev/null and b/lldb/test/API/tools/lldb-vscode/coreFile/linux-x86_64.out differ
index 2294659..20c7131 100644 (file)
@@ -181,15 +181,15 @@ for processes. Currently MacOS is the only platform that supports this.
 
 ### Loading a Core File
 
-Loading a core file can use the `"attach"` request along with the
-`"attachCommands"` to implement a custom attach:
+This loads the coredump file `/cores/123.core` associated with the program
+`/tmp/a.out`:
 
 ```javascript
 {
-  "name": "Attach to Name (wait)",
+  "name": "Load coredump",
   "type": "lldb-vscode",
   "request": "attach",
-  "attachCommands": ["target create -c /path/to/123.core /path/to/executable"],
-  "stopOnEntry": false
+  "coreFile": "/cores/123.core",
+  "program": "/tmp/a.out"
 }
 ```
index b267ea0..764eded 100644 (file)
@@ -530,7 +530,9 @@ void request_attach(const llvm::json::Object &request) {
   g_vsc.stop_commands = GetStrings(arguments, "stopCommands");
   g_vsc.exit_commands = GetStrings(arguments, "exitCommands");
   auto attachCommands = GetStrings(arguments, "attachCommands");
-  g_vsc.stop_at_entry = GetBoolean(arguments, "stopOnEntry", false);
+  llvm::StringRef core_file = GetString(arguments, "coreFile");
+  g_vsc.stop_at_entry =
+      core_file.empty() ? GetBoolean(arguments, "stopOnEntry", false) : true;
   const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot");
 
   // This is a hack for loading DWARF in .o files on Mac where the .o files
@@ -568,7 +570,10 @@ void request_attach(const llvm::json::Object &request) {
     // Disable async events so the attach will be successful when we return from
     // the launch call and the launch will happen synchronously
     g_vsc.debugger.SetAsync(false);
-    g_vsc.target.Attach(attach_info, error);
+    if (core_file.empty())
+      g_vsc.target.Attach(attach_info, error);
+    else
+      g_vsc.target.LoadCore(core_file.data(), error);
     // Reenable async events
     g_vsc.debugger.SetAsync(true);
   } else {
@@ -583,7 +588,7 @@ void request_attach(const llvm::json::Object &request) {
 
   SetSourceMapFromArguments(*arguments);
 
-  if (error.Success()) {
+  if (error.Success() && core_file.empty()) {
     auto attached_pid = g_vsc.target.GetProcess().GetProcessID();
     if (attached_pid == LLDB_INVALID_PROCESS_ID) {
       if (attachCommands.empty())
index 8dabf3d..1df16d0 100644 (file)
                                                        },
                                                        "exitCommands": {
                                                                "type": "array",
-                                                                       "description": "Commands executed at the end of debugging session.",
-                                                                       "default": []
+                                                               "description": "Commands executed at the end of debugging session.",
+                                                               "default": []
+                                                       },
+                                                       "coreFile": {
+                                                               "type": "string",
+                                                               "description": "Path to the core file to debug."
                                                        }
                                                }
                                        }