[Lldb-commits] [lldb] [LLDB] Extract process arguments from core dump for Linux (PR #185338)

Jasmine Tang via lldb-commits lldb-commits at lists.llvm.org
Sun Mar 8 19:48:40 PDT 2026


https://github.com/badumbatish updated https://github.com/llvm/llvm-project/pull/185338

>From bef702f9c9a9f487c3cb9e86f874befbaff85b34 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Sun, 8 Mar 2026 19:07:56 -0700
Subject: [PATCH 1/2] Precommit for core arg

---
 .../functionalities/postmortem/elf-core/TestLinuxCore.py  | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
index 743eae126457a..d75675b92864a 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -58,6 +58,14 @@ def test_x86_64(self):
         """Test that lldb can read the process information from an x86_64 linux core file."""
         self.do_test("linux-x86_64", self._x86_64_pid, self._x86_64_regions, "a.out")
 
+    @skipIfLLVMTargetMissing("X86")
+    def test_x86_64_core_generated(self):
+        """Test that lldb can read the argument used for the process from an x86_64 linux core file."""
+        result = lldb.SBCommandReturnObject()
+        self.dbg.GetCommandInterpreter().HandleCommand("target create linux-x86_64.out --core linux-x86_64.core", result)
+        out = result.GetOutput()
+        self.assertNotIn("Core was generated by", out, "Command line arg from pr_psargs should not be shown yet")
+
     @skipIfLLVMTargetMissing("SystemZ")
     def test_s390x(self):
         """Test that lldb can read the process information from an s390x linux core file."""

>From f69d577cc2649ba0ebde5741494831ee4dde2e74 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Sun, 8 Mar 2026 19:09:23 -0700
Subject: [PATCH 2/2] Implemented lldb core arg for linux

---
 lldb/include/lldb/Target/Process.h                 | 14 ++++++++++++++
 lldb/source/Commands/CommandObjectTarget.cpp       |  4 ++++
 .../Plugins/Process/elf-core/ProcessElfCore.cpp    |  7 +++++++
 .../Plugins/Process/elf-core/ProcessElfCore.h      |  2 ++
 lldb/source/Target/Process.cpp                     |  6 +++++-
 .../postmortem/elf-core/TestLinuxCore.py           | 10 ++++++++--
 6 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index c4eb8cf3694b1..52a4e7dd57f1d 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1521,6 +1521,20 @@ class Process : public std::enable_shared_from_this<Process>,
   /// \return
   ///     File path to the core file.
   virtual FileSpec GetCoreFile() const { return {}; }
+  std::string GetCoreFileCommandString() {
+    if (!IsLiveDebugSession() && GetPluginName().contains("core")) {
+      ProcessInstanceInfo info;
+      if (GetProcessInfo(info)) {
+        const Args &args = info.GetArguments();
+        if (!args.empty()) {
+          std::string cmd;
+          args.GetCommandString(cmd);
+          return cmd;
+        }
+      }
+    }
+    return {};
+  }
 
   /// Before lldb detaches from a process, it warns the user that they are
   /// about to lose their debug session. In some cases, this warning doesn't
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 59ccf390dea31..5f9a52c56fc1f 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -433,6 +433,10 @@ class CommandObjectTargetCreate : public CommandObjectParsed {
             result.AppendMessageWithFormatv(
                 "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
                 target_sp->GetArchitecture().GetArchitectureName());
+            std::string cmd = process_sp->GetCoreFileCommandString();
+            if (!cmd.empty())
+              result.AppendMessageWithFormatv("Core was generated by `{0}`.\n",
+                                              cmd);
             result.SetStatus(eReturnStatusSuccessFinishNoResult);
             on_error.release();
           }
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 3888b6d4f90ec..056398c02f0ed 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -987,6 +987,9 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
       thread_data.name.assign (prpsinfo.pr_fname, strnlen (prpsinfo.pr_fname, sizeof (prpsinfo.pr_fname)));
       SetID(prpsinfo.pr_pid);
       m_executable_name = thread_data.name;
+      m_process_args_string.assign(
+          prpsinfo.pr_psargs,
+          strnlen(prpsinfo.pr_psargs, sizeof(prpsinfo.pr_psargs)));
       break;
     }
     case ELF::NT_SIGINFO: {
@@ -1169,5 +1172,9 @@ bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) {
     info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
                            add_exe_file_as_first_arg);
   }
+  if (!m_process_args_string.empty()) {
+    Args args(m_process_args_string);
+    info.SetArguments(args, true);
+  }
   return true;
 }
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
index 7eda33be8634c..aec13b8ee9ba4 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -155,6 +155,8 @@ class ProcessElfCore : public lldb_private::PostMortemProcess {
   // Executable name found from the ELF PRPSINFO
   std::string m_executable_name;
 
+  // Command line args string found from the ELF PRPSINFO (pr_psargs)
+  std::string m_process_args_string;
   // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
   llvm::Error ParseThreadContextsFromNoteSegment(
       const elf::ELFProgramHeader &segment_header,
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index b1a9a25171931..282d483828058 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -5948,8 +5948,12 @@ void Process::GetStatus(Stream &strm) {
     } else {
       if (state == eStateConnected)
         strm.Printf("Connected to remote target.\n");
-      else
+      else {
         strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
+        std::string cmd = GetCoreFileCommandString();
+        if (!cmd.empty())
+          strm.Printf("Core was generated by `%s`.\n", cmd.c_str());
+      }
     }
   } else {
     strm.Printf("Process %" PRIu64 " is running.\n", GetID());
diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
index d75675b92864a..d39e19d867915 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -62,9 +62,15 @@ def test_x86_64(self):
     def test_x86_64_core_generated(self):
         """Test that lldb can read the argument used for the process from an x86_64 linux core file."""
         result = lldb.SBCommandReturnObject()
-        self.dbg.GetCommandInterpreter().HandleCommand("target create linux-x86_64.out --core linux-x86_64.core", result)
+        self.dbg.GetCommandInterpreter().HandleCommand(
+            "target create linux-x86_64.out --core linux-x86_64.core", result
+        )
         out = result.GetOutput()
-        self.assertNotIn("Core was generated by", out, "Command line arg from pr_psargs should not be shown yet")
+        self.assertIn(
+            "Core was generated by `/test/test/test/test/test/test",
+            out,
+            "Command line arg from pr_psargs should be shown.",
+        )
 
     @skipIfLLVMTargetMissing("SystemZ")
     def test_s390x(self):



More information about the lldb-commits mailing list