[Lldb-commits] [lldb] [llvm] [LLDB] Extract process arguments from core dump for Linux (PR #185338)
Jasmine Tang via lldb-commits
lldb-commits at lists.llvm.org
Fri Apr 17 10:58:20 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 01/15] 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 02/15] 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):
>From 92737f32c269ef414fd01f7c2bb501a8fbfd4540 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Mon, 9 Mar 2026 17:13:17 -0700
Subject: [PATCH 03/15] Address PR Reviews
---
lldb/include/lldb/Target/Process.h | 26 +++++++++++---------
lldb/source/Commands/CommandObjectTarget.cpp | 4 ++-
lldb/source/Target/Process.cpp | 8 +++---
3 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 52a4e7dd57f1d..ad80947031543 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -47,6 +47,7 @@
#include "lldb/Target/Trace.h"
#include "lldb/Utility/AddressableBits.h"
#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/Listener.h"
@@ -1521,18 +1522,19 @@ 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;
- }
- }
- }
+
+ /// Provide arguments of a command that triggers a core dump
+ /// Only available when we have a core file
+ ///
+ /// \return
+ /// Args of a core dump
+ Args GetCoreFileCommandString() {
+ if (!GetCoreFile())
+ return {};
+
+ ProcessInstanceInfo info;
+ if (GetProcessInfo(info))
+ return info.GetArguments();
return {};
}
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 5f9a52c56fc1f..b4559ac02be5f 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -433,7 +433,9 @@ 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();
+ Args args = process_sp->GetCoreFileCommandString();
+ std::string cmd;
+ args.GetCommandString(cmd);
if (!cmd.empty())
result.AppendMessageWithFormatv("Core was generated by `{0}`.\n",
cmd);
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 282d483828058..478434f169741 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -5946,11 +5946,13 @@ void Process::GetStatus(Stream &strm) {
GetID(), exit_status, exit_status,
exit_description ? exit_description : "");
} else {
- if (state == eStateConnected)
+ 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();
+ Args args = GetCoreFileCommandString();
+ std::string cmd;
+ args.GetCommandString(cmd);
if (!cmd.empty())
strm.Printf("Core was generated by `%s`.\n", cmd.c_str());
}
>From 181c6a0f55032dc25dd89a81116799386557ef6b Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Fri, 13 Mar 2026 14:41:42 -0700
Subject: [PATCH 04/15] Addresses PR reviews #2
---
lldb/include/lldb/Target/Process.h | 8 ++--
lldb/source/Commands/CommandObjectTarget.cpp | 9 ++--
.../Process/elf-core/ProcessElfCore.cpp | 9 ++--
.../Plugins/Process/elf-core/ProcessElfCore.h | 5 ++-
lldb/source/Target/Process.cpp | 9 ++--
.../postmortem/elf-core/TestLinuxCore.py | 41 +++++++++++++++++--
6 files changed, 60 insertions(+), 21 deletions(-)
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index ad80947031543..068398b2d10b9 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1523,12 +1523,12 @@ class Process : public std::enable_shared_from_this<Process>,
/// File path to the core file.
virtual FileSpec GetCoreFile() const { return {}; }
- /// Provide arguments of a command that triggers a core dump
- /// Only available when we have a core file
+ /// Provide arguments of a command that triggered a core dump.
///
/// \return
- /// Args of a core dump
- Args GetCoreFileCommandString() {
+ /// The arguments that created the core dump.
+ /// If this process is a live debug session, returns an empty list of arguments.
+ Args GetCoreFileArgs() {
if (!GetCoreFile())
return {};
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index b4559ac02be5f..2fe68a4cc4ae8 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -433,11 +433,14 @@ class CommandObjectTargetCreate : public CommandObjectParsed {
result.AppendMessageWithFormatv(
"Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
target_sp->GetArchitecture().GetArchitectureName());
- Args args = process_sp->GetCoreFileCommandString();
std::string cmd;
- args.GetCommandString(cmd);
+ process_sp->GetCoreFileArgs().GetCommandString(cmd);
+ std::string msg = "Core was generated by '{0}'";
+ if (cmd.size() == 79)
+ msg += " (command might be truncated).";
+ msg += ".";
if (!cmd.empty())
- result.AppendMessageWithFormatv("Core was generated by `{0}`.\n",
+ result.AppendMessageWithFormatv(msg.c_str(),
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 056398c02f0ed..4a60996ae03df 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -987,9 +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(
+ m_process_args = Args(llvm::StringRef(
prpsinfo.pr_psargs,
- strnlen(prpsinfo.pr_psargs, sizeof(prpsinfo.pr_psargs)));
+ strnlen(prpsinfo.pr_psargs, sizeof(prpsinfo.pr_psargs))));
break;
}
case ELF::NT_SIGINFO: {
@@ -1172,9 +1172,8 @@ 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);
+ if (!m_process_args.empty()) {
+ info.SetArguments(m_process_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 aec13b8ee9ba4..3e1595c484da5 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -21,6 +21,7 @@
#include <vector>
#include "lldb/Target/PostMortemProcess.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/Status.h"
#include "Plugins/ObjectFile/ELF/ELFHeader.h"
@@ -155,8 +156,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;
+ // Command line args found from the ELF PRPSINFO (pr_psargs)
+ lldb_private::Args m_process_args;
// 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 478434f169741..9110735ae7644 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -5950,11 +5950,14 @@ void Process::GetStatus(Stream &strm) {
strm.Printf("Connected to remote target.\n");
} else {
strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
- Args args = GetCoreFileCommandString();
std::string cmd;
- args.GetCommandString(cmd);
+ GetCoreFileArgs().GetCommandString(cmd);
+ std::string msg = "Core was generated by '%s'";
+ if (cmd.size() == 79)
+ msg += " (command might be truncated)";
+ msg += ".\n";
if (!cmd.empty())
- strm.Printf("Core was generated by `%s`.\n", cmd.c_str());
+ strm.Printf(msg.c_str(), cmd.c_str());
}
}
} else {
diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
index d39e19d867915..1f89b3a8cb28b 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -59,17 +59,50 @@ def test_x86_64(self):
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."""
+ def test_x86_64_core_args_truncated(self):
+ """Test that a truncated pr_psargs shows a truncation warning."""
result = lldb.SBCommandReturnObject()
self.dbg.GetCommandInterpreter().HandleCommand(
"target create linux-x86_64.out --core linux-x86_64.core", result
)
out = result.GetOutput()
+ core_arg_msg = "Core was generated by '/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/tes' (command might be truncated)."
self.assertIn(
- "Core was generated by `/test/test/test/test/test/test",
+ core_arg_msg,
out,
- "Command line arg from pr_psargs should be shown.",
+ "Truncated pr_psargs should show truncation warning when core file is loaded.",
+ )
+ self.dbg.GetCommandInterpreter().HandleCommand("process status", result)
+ out = result.GetOutput()
+ self.assertIn(
+ core_arg_msg,
+ out,
+ "Truncated pr_psargs should show truncation warning when process status is invoked.",
+ )
+
+ @skipIfLLVMTargetMissing("X86")
+ def test_x86_64_core_args_not_truncated(self):
+ """Test that a short pr_psargs does not show a truncation warning."""
+ result = lldb.SBCommandReturnObject()
+ self.dbg.GetCommandInterpreter().HandleCommand(
+ # this core file has pr_psargs='./a.out', which is short
+ # and should not trigger the truncation warning.
+ "target create --core linux-fpr_sse_x86_64.core",
+ result,
+ )
+ out = result.GetOutput()
+ core_arg_msg = "Core was generated by './a.out'."
+ self.assertIn(
+ core_arg_msg,
+ out,
+ "Short pr_psargs should show the core args without truncation warning when core file is loaded.",
+ )
+ self.dbg.GetCommandInterpreter().HandleCommand("process status", result)
+ out = result.GetOutput()
+ self.assertIn(
+ core_arg_msg,
+ out,
+ "Short pr_psargs should show the core args without truncation warning when process status is invoked.",
)
@skipIfLLVMTargetMissing("SystemZ")
>From 6c4e534db84d265ef2aed2ba19823a5221aa85d5 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Fri, 13 Mar 2026 15:11:40 -0700
Subject: [PATCH 05/15] Reformat
---
lldb/include/lldb/Target/Process.h | 5 +++--
lldb/source/Commands/CommandObjectTarget.cpp | 3 +--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 068398b2d10b9..c1bb6599a5c05 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1526,8 +1526,9 @@ class Process : public std::enable_shared_from_this<Process>,
/// Provide arguments of a command that triggered a core dump.
///
/// \return
- /// The arguments that created the core dump.
- /// If this process is a live debug session, returns an empty list of arguments.
+ /// The arguments that created the core dump.
+ /// If this process is a live debug session, returns an empty list of
+ /// arguments.
Args GetCoreFileArgs() {
if (!GetCoreFile())
return {};
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 2fe68a4cc4ae8..5e036525020af 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -440,8 +440,7 @@ class CommandObjectTargetCreate : public CommandObjectParsed {
msg += " (command might be truncated).";
msg += ".";
if (!cmd.empty())
- result.AppendMessageWithFormatv(msg.c_str(),
- cmd);
+ result.AppendMessageWithFormatv(msg.c_str(), cmd);
result.SetStatus(eReturnStatusSuccessFinishNoResult);
on_error.release();
}
>From df29bc19595fa5906403c86cd213d4422d1e9fc6 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Tue, 31 Mar 2026 22:28:37 -0700
Subject: [PATCH 06/15] Change to self.expect for testing core args
---
.../postmortem/elf-core/TestLinuxCore.py | 50 +++++++------------
1 file changed, 17 insertions(+), 33 deletions(-)
diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
index 1f89b3a8cb28b..2a8d8dc8954f2 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -61,48 +61,32 @@ def test_x86_64(self):
@skipIfLLVMTargetMissing("X86")
def test_x86_64_core_args_truncated(self):
"""Test that a truncated pr_psargs shows a truncation warning."""
- result = lldb.SBCommandReturnObject()
- self.dbg.GetCommandInterpreter().HandleCommand(
- "target create linux-x86_64.out --core linux-x86_64.core", result
- )
- out = result.GetOutput()
core_arg_msg = "Core was generated by '/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/tes' (command might be truncated)."
- self.assertIn(
- core_arg_msg,
- out,
- "Truncated pr_psargs should show truncation warning when core file is loaded.",
+ self.expect(
+ "target create linux-x86_64.out --core linux-x86_64.core",
+ msg="Truncated pr_psargs should show truncation warning when core file is loaded.",
+ substrs=[core_arg_msg],
)
- self.dbg.GetCommandInterpreter().HandleCommand("process status", result)
- out = result.GetOutput()
- self.assertIn(
- core_arg_msg,
- out,
- "Truncated pr_psargs should show truncation warning when process status is invoked.",
+ self.expect(
+ "process status",
+ msg="Truncated pr_psargs should show truncation warning when process status is invoked.",
+ substrs=[core_arg_msg],
)
@skipIfLLVMTargetMissing("X86")
def test_x86_64_core_args_not_truncated(self):
"""Test that a short pr_psargs does not show a truncation warning."""
- result = lldb.SBCommandReturnObject()
- self.dbg.GetCommandInterpreter().HandleCommand(
- # this core file has pr_psargs='./a.out', which is short
- # and should not trigger the truncation warning.
- "target create --core linux-fpr_sse_x86_64.core",
- result,
- )
- out = result.GetOutput()
core_arg_msg = "Core was generated by './a.out'."
- self.assertIn(
- core_arg_msg,
- out,
- "Short pr_psargs should show the core args without truncation warning when core file is loaded.",
+ # This core file has pr_psargs='./a.out', which is short.
+ self.expect(
+ "target create --core linux-fpr_sse_x86_64.core",
+ msg="Short pr_psargs should show the core args without truncation warning when core file is loaded.",
+ substrs=[core_arg_msg],
)
- self.dbg.GetCommandInterpreter().HandleCommand("process status", result)
- out = result.GetOutput()
- self.assertIn(
- core_arg_msg,
- out,
- "Short pr_psargs should show the core args without truncation warning when process status is invoked.",
+ self.expect(
+ "process status",
+ msg="Short pr_psargs should show the core args without truncation warning when process status is invoked.",
+ substrs=[core_arg_msg],
)
@skipIfLLVMTargetMissing("SystemZ")
>From e3779472cf464ddac39bda7045676c6b5a2ff85e Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Tue, 31 Mar 2026 22:32:59 -0700
Subject: [PATCH 07/15] Fix nit around brace of conditionals and
eStateConnected
---
lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp | 3 +--
lldb/source/Target/Process.cpp | 7 ++++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 4a60996ae03df..8130079f83d22 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -1172,8 +1172,7 @@ bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) {
info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
add_exe_file_as_first_arg);
}
- if (!m_process_args.empty()) {
+ if (!m_process_args.empty())
info.SetArguments(m_process_args, true);
- }
return true;
}
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 9110735ae7644..d2881a8a8725e 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -5946,9 +5946,9 @@ void Process::GetStatus(Stream &strm) {
GetID(), exit_status, exit_status,
exit_description ? exit_description : "");
} else {
- if (state == eStateConnected) {
+ if (state == eStateConnected)
strm.Printf("Connected to remote target.\n");
- } else {
+ else if (!IsLiveDebugSession()) {
strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
std::string cmd;
GetCoreFileArgs().GetCommandString(cmd);
@@ -5958,7 +5958,8 @@ void Process::GetStatus(Stream &strm) {
msg += ".\n";
if (!cmd.empty())
strm.Printf(msg.c_str(), cmd.c_str());
- }
+ } else
+ strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
}
} else {
strm.Printf("Process %" PRIu64 " is running.\n", GetID());
>From 7839775dca236a0607979a82ee3f188d5faf25c1 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Tue, 31 Mar 2026 22:42:51 -0700
Subject: [PATCH 08/15] Transition to better control flow for core arg
truncated warning
---
lldb/source/Commands/CommandObjectTarget.cpp | 11 ++++++-----
lldb/source/Target/Process.cpp | 11 ++++++-----
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 5e036525020af..1073137d9a578 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -435,12 +435,13 @@ class CommandObjectTargetCreate : public CommandObjectParsed {
target_sp->GetArchitecture().GetArchitectureName());
std::string cmd;
process_sp->GetCoreFileArgs().GetCommandString(cmd);
- std::string msg = "Core was generated by '{0}'";
- if (cmd.size() == 79)
- msg += " (command might be truncated).";
- msg += ".";
- if (!cmd.empty())
+ if (!cmd.empty()) {
+ std::string msg = "Core was generated by '{0}'";
+ if (cmd.size() == 79)
+ msg += " (command might be truncated).";
+ msg += ".";
result.AppendMessageWithFormatv(msg.c_str(), cmd);
+ }
result.SetStatus(eReturnStatusSuccessFinishNoResult);
on_error.release();
}
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index d2881a8a8725e..53a31a039fa2e 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -5952,12 +5952,13 @@ void Process::GetStatus(Stream &strm) {
strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
std::string cmd;
GetCoreFileArgs().GetCommandString(cmd);
- std::string msg = "Core was generated by '%s'";
- if (cmd.size() == 79)
- msg += " (command might be truncated)";
- msg += ".\n";
- if (!cmd.empty())
+ if (!cmd.empty()) {
+ std::string msg = "Core was generated by '%s'";
+ if (cmd.size() == 79)
+ msg += " (command might be truncated)";
+ msg += ".\n";
strm.Printf(msg.c_str(), cmd.c_str());
+ }
} else
strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
}
>From 945d28b1b35a7b3ca88ae9003e4fc784b885675a Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Tue, 31 Mar 2026 23:18:48 -0700
Subject: [PATCH 09/15] Transition to dedicated CoreArgs class
---
lldb/include/lldb/Target/Process.h | 33 ++++++++++++-------
lldb/source/Commands/CommandObjectTarget.cpp | 11 ++-----
.../Process/elf-core/ProcessElfCore.cpp | 7 ++++
.../Plugins/Process/elf-core/ProcessElfCore.h | 1 +
lldb/source/Target/Process.cpp | 11 ++-----
5 files changed, 34 insertions(+), 29 deletions(-)
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index c1bb6599a5c05..5f964ed17d607 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -346,6 +346,26 @@ inline bool operator!=(const ProcessModID &lhs, const ProcessModID &rhs) {
return (!lhs.StopIDEqual(rhs) || !lhs.MemoryIDEqual(rhs));
}
+class CoreArgs {
+ const Args &args;
+ bool might_truncate;
+
+public:
+ CoreArgs(const Args &args, bool might_truncate)
+ : args(args), might_truncate(might_truncate) {}
+
+ void FormatAsMessage(Stream &stream) {
+ std::string cmd;
+ args.GetCommandString(cmd);
+ if (!cmd.empty()) {
+ stream << "Core was generated by '" << cmd << "'";
+ if (!this->might_truncate)
+ stream << " (command might be truncated)";
+ stream << ".\n.";
+ }
+ }
+};
+
/// \class Process Process.h "lldb/Target/Process.h"
/// A plug-in interface definition class for debugging a process.
class Process : public std::enable_shared_from_this<Process>,
@@ -1527,17 +1547,8 @@ class Process : public std::enable_shared_from_this<Process>,
///
/// \return
/// The arguments that created the core dump.
- /// If this process is a live debug session, returns an empty list of
- /// arguments.
- Args GetCoreFileArgs() {
- if (!GetCoreFile())
- return {};
-
- ProcessInstanceInfo info;
- if (GetProcessInfo(info))
- return info.GetArguments();
- return {};
- }
+ /// If this process is a live debug session, returns a std::nullopt.
+ virtual std::optional<CoreArgs> GetCoreFileArgs() { return std::nullopt; }
/// 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 1073137d9a578..da1db7c78e66e 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -433,15 +433,8 @@ 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->GetCoreFileArgs().GetCommandString(cmd);
- if (!cmd.empty()) {
- std::string msg = "Core was generated by '{0}'";
- if (cmd.size() == 79)
- msg += " (command might be truncated).";
- msg += ".";
- result.AppendMessageWithFormatv(msg.c_str(), cmd);
- }
+ if (auto core_args = process_sp->GetCoreFileArgs())
+ core_args->FormatAsMessage(result.GetOutputStream());
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 8130079f83d22..f4e15e9cc5065 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -1161,6 +1161,13 @@ DataExtractor ProcessElfCore::GetAuxvData() {
m_auxv.GetAddressByteSize() == GetAddressByteSize()));
return DataExtractor(m_auxv);
}
+std::optional<CoreArgs> ProcessElfCore::GetCoreFileArgs() {
+ if (m_process_args.empty())
+ return std::nullopt;
+ std::string cmd;
+ m_process_args.GetCommandString(cmd);
+ return CoreArgs(m_process_args, cmd.size() == 79);
+}
bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) {
info.Clear();
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
index 3e1595c484da5..6db10b195e976 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -97,6 +97,7 @@ class ProcessElfCore : public lldb_private::PostMortemProcess {
// Returns AUXV structure found in the core file
lldb_private::DataExtractor GetAuxvData() override;
+ std::optional<lldb_private::CoreArgs> GetCoreFileArgs() override;
bool GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override;
protected:
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 53a31a039fa2e..e16547346b8f3 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -5950,15 +5950,8 @@ void Process::GetStatus(Stream &strm) {
strm.Printf("Connected to remote target.\n");
else if (!IsLiveDebugSession()) {
strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
- std::string cmd;
- GetCoreFileArgs().GetCommandString(cmd);
- if (!cmd.empty()) {
- std::string msg = "Core was generated by '%s'";
- if (cmd.size() == 79)
- msg += " (command might be truncated)";
- msg += ".\n";
- strm.Printf(msg.c_str(), cmd.c_str());
- }
+ if (auto core_args = GetCoreFileArgs())
+ core_args->FormatAsMessage(strm);
} else
strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
}
>From 92741337f9ed83d2cf19dce745c9a71d3e5c5180 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Tue, 31 Mar 2026 23:51:55 -0700
Subject: [PATCH 10/15] Fix might_truncate bug in FormatAsMessage
---
lldb/include/lldb/Target/Process.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 5f964ed17d607..fce7e13431119 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -359,7 +359,7 @@ class CoreArgs {
args.GetCommandString(cmd);
if (!cmd.empty()) {
stream << "Core was generated by '" << cmd << "'";
- if (!this->might_truncate)
+ if (this->might_truncate)
stream << " (command might be truncated)";
stream << ".\n.";
}
>From ac33826ca35c155ef0afdaf2e06f4ca0c9fa34a8 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Sat, 4 Apr 2026 22:39:45 -0700
Subject: [PATCH 11/15] Transition process status show core args with -v only
---
lldb/include/lldb/Target/Process.h | 2 +-
lldb/source/Commands/CommandObjectProcess.cpp | 2 +-
lldb/source/Target/Process.cpp | 5 +++--
.../postmortem/elf-core/TestLinuxCore.py | 16 ++++++++++++++--
4 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index fce7e13431119..3f4d6db2dd23c 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1317,7 +1317,7 @@ class Process : public std::enable_shared_from_this<Process>,
const EvaluateExpressionOptions &options,
DiagnosticManager &diagnostic_manager);
- void GetStatus(Stream &ostrm);
+ void GetStatus(Stream &ostrm, bool is_verbose = false);
size_t GetThreadStatus(Stream &ostrm, bool only_threads_with_stop_reason,
uint32_t start_frame, uint32_t num_frames,
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index ca210e145d07e..26075301887d7 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -1459,7 +1459,7 @@ class CommandObjectProcessStatus : public CommandObjectParsed {
const uint32_t num_frames = 1;
const uint32_t num_frames_with_source = 1;
const bool stop_format = true;
- process->GetStatus(strm);
+ process->GetStatus(strm, m_options.m_verbose);
process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
num_frames, num_frames_with_source, stop_format);
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index e16547346b8f3..fe23650a25c5c 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -5936,7 +5936,7 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
return return_value;
}
-void Process::GetStatus(Stream &strm) {
+void Process::GetStatus(Stream &strm, bool is_verbose) {
const StateType state = GetState();
if (StateIsStoppedState(state, false)) {
if (state == eStateExited) {
@@ -5950,7 +5950,8 @@ void Process::GetStatus(Stream &strm) {
strm.Printf("Connected to remote target.\n");
else if (!IsLiveDebugSession()) {
strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
- if (auto core_args = GetCoreFileArgs())
+ auto core_args = GetCoreFileArgs();
+ if (core_args && is_verbose)
core_args->FormatAsMessage(strm);
} else
strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
index 2a8d8dc8954f2..dd6661efe0a77 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -69,7 +69,13 @@ def test_x86_64_core_args_truncated(self):
)
self.expect(
"process status",
- msg="Truncated pr_psargs should show truncation warning when process status is invoked.",
+ msg="Core args should not be shown at all when process status (without -v) is invoked.",
+ matching=False,
+ substrs=[core_arg_msg],
+ )
+ self.expect(
+ "process status -v",
+ msg="Truncated pr_psargs should show truncation warning when process status -v is invoked.",
substrs=[core_arg_msg],
)
@@ -85,7 +91,13 @@ def test_x86_64_core_args_not_truncated(self):
)
self.expect(
"process status",
- msg="Short pr_psargs should show the core args without truncation warning when process status is invoked.",
+ msg="Core args should not be shown at all when process status (without -v) is invoked.",
+ matching=False,
+ substrs=[core_arg_msg],
+ )
+ self.expect(
+ "process status -v",
+ msg="Short pr_psargs should show the core args without truncation warning when process status -v is invoked.",
substrs=[core_arg_msg],
)
>From 368649efa3b1d294eacb64ce3f8f6f453f3763ad Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Wed, 15 Apr 2026 19:04:54 -0700
Subject: [PATCH 12/15] Address PR reviews
---
lldb/include/lldb/Target/Process.h | 42 ++++++++++---------
lldb/source/Commands/CommandObjectTarget.cpp | 2 +-
.../Process/elf-core/ProcessElfCore.cpp | 18 ++++----
.../Plugins/Process/elf-core/ProcessElfCore.h | 4 +-
lldb/source/Target/Process.cpp | 2 +-
.../postmortem/elf-core/TestLinuxCore.py | 2 +-
6 files changed, 37 insertions(+), 33 deletions(-)
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 3f4d6db2dd23c..af70d5086b7dc 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -346,26 +346,6 @@ inline bool operator!=(const ProcessModID &lhs, const ProcessModID &rhs) {
return (!lhs.StopIDEqual(rhs) || !lhs.MemoryIDEqual(rhs));
}
-class CoreArgs {
- const Args &args;
- bool might_truncate;
-
-public:
- CoreArgs(const Args &args, bool might_truncate)
- : args(args), might_truncate(might_truncate) {}
-
- void FormatAsMessage(Stream &stream) {
- std::string cmd;
- args.GetCommandString(cmd);
- if (!cmd.empty()) {
- stream << "Core was generated by '" << cmd << "'";
- if (this->might_truncate)
- stream << " (command might be truncated)";
- stream << ".\n.";
- }
- }
-};
-
/// \class Process Process.h "lldb/Target/Process.h"
/// A plug-in interface definition class for debugging a process.
class Process : public std::enable_shared_from_this<Process>,
@@ -1543,6 +1523,28 @@ class Process : public std::enable_shared_from_this<Process>,
/// File path to the core file.
virtual FileSpec GetCoreFile() const { return {}; }
+ class CoreArgs {
+ std::string cmd;
+ bool might_be_truncated;
+
+ public:
+ CoreArgs() = default;
+ CoreArgs(const std::string &args, bool might_be_truncated)
+ : cmd(args), might_be_truncated(might_be_truncated) {}
+
+ void Format(Stream &stream) {
+ if (!cmd.empty()) {
+ stream << "Core was generated by '" << cmd << "'";
+ if (this->might_be_truncated)
+ stream << " (command might be truncated)";
+ stream << ".\n.";
+ }
+ }
+ bool empty() { return cmd.empty(); }
+
+ Args as_args() { return Args(cmd); }
+ };
+
/// Provide arguments of a command that triggered a core dump.
///
/// \return
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index da1db7c78e66e..c6f08a1b4d5e9 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -434,7 +434,7 @@ class CommandObjectTargetCreate : public CommandObjectParsed {
"Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
target_sp->GetArchitecture().GetArchitectureName());
if (auto core_args = process_sp->GetCoreFileArgs())
- core_args->FormatAsMessage(result.GetOutputStream());
+ core_args->Format(result.GetOutputStream());
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 f4e15e9cc5065..bda1c16f71aef 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -987,9 +987,13 @@ 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 = Args(llvm::StringRef(
- prpsinfo.pr_psargs,
- strnlen(prpsinfo.pr_psargs, sizeof(prpsinfo.pr_psargs))));
+ auto core_arg = llvm::StringRef(prpsinfo.pr_psargs,
+ strnlen(prpsinfo.pr_psargs,
+ sizeof(prpsinfo.pr_psargs)))
+ .str();
+ // pr_psargs's char array used to represent arguments is only 80 character long
+ // (\0 included), hence 79.
+ m_process_args = CoreArgs(core_arg, core_arg.size() == 79);
break;
}
case ELF::NT_SIGINFO: {
@@ -1161,12 +1165,10 @@ DataExtractor ProcessElfCore::GetAuxvData() {
m_auxv.GetAddressByteSize() == GetAddressByteSize()));
return DataExtractor(m_auxv);
}
-std::optional<CoreArgs> ProcessElfCore::GetCoreFileArgs() {
+std::optional<Process::CoreArgs> ProcessElfCore::GetCoreFileArgs() {
if (m_process_args.empty())
return std::nullopt;
- std::string cmd;
- m_process_args.GetCommandString(cmd);
- return CoreArgs(m_process_args, cmd.size() == 79);
+ return m_process_args;
}
bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) {
@@ -1180,6 +1182,6 @@ bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) {
add_exe_file_as_first_arg);
}
if (!m_process_args.empty())
- info.SetArguments(m_process_args, true);
+ info.SetArguments(m_process_args.as_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 6db10b195e976..2b6b34075252f 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -97,7 +97,7 @@ class ProcessElfCore : public lldb_private::PostMortemProcess {
// Returns AUXV structure found in the core file
lldb_private::DataExtractor GetAuxvData() override;
- std::optional<lldb_private::CoreArgs> GetCoreFileArgs() override;
+ std::optional<Process::CoreArgs> GetCoreFileArgs() override;
bool GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override;
protected:
@@ -158,7 +158,7 @@ class ProcessElfCore : public lldb_private::PostMortemProcess {
std::string m_executable_name;
// Command line args found from the ELF PRPSINFO (pr_psargs)
- lldb_private::Args m_process_args;
+ Process::CoreArgs m_process_args;
// 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 fe23650a25c5c..da08071eec229 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -5952,7 +5952,7 @@ void Process::GetStatus(Stream &strm, bool is_verbose) {
strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
auto core_args = GetCoreFileArgs();
if (core_args && is_verbose)
- core_args->FormatAsMessage(strm);
+ core_args->Format(strm);
} else
strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
}
diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
index dd6661efe0a77..50eb432d12ae9 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -82,7 +82,7 @@ def test_x86_64_core_args_truncated(self):
@skipIfLLVMTargetMissing("X86")
def test_x86_64_core_args_not_truncated(self):
"""Test that a short pr_psargs does not show a truncation warning."""
- core_arg_msg = "Core was generated by './a.out'."
+ core_arg_msg = "Core was generated by './a.out '."
# This core file has pr_psargs='./a.out', which is short.
self.expect(
"target create --core linux-fpr_sse_x86_64.core",
>From 7b18df1aad8e4b7c55eabf448e35ba20caeb92aa Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Wed, 15 Apr 2026 19:11:10 -0700
Subject: [PATCH 13/15] Reformat codebase
---
lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index bda1c16f71aef..6b029b6f13612 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -991,7 +991,8 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
strnlen(prpsinfo.pr_psargs,
sizeof(prpsinfo.pr_psargs)))
.str();
- // pr_psargs's char array used to represent arguments is only 80 character long
+ // pr_psargs's char array used to represent arguments is only 80 character
+ // long
// (\0 included), hence 79.
m_process_args = CoreArgs(core_arg, core_arg.size() == 79);
break;
>From 1342a01891eeb57638611385a4d91982f43f70ce Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Fri, 17 Apr 2026 10:44:31 -0700
Subject: [PATCH 14/15] Fix PR with reviews
---
lldb/include/lldb/Target/Process.h | 27 ++++++++++---------
.../Process/elf-core/ProcessElfCore.cpp | 12 +++++----
lldb/source/Target/Process.cpp | 8 +++---
.../postmortem/elf-core/TestLinuxCore.py | 6 ++---
llvm/docs/ReleaseNotes.md | 2 ++
5 files changed, 29 insertions(+), 26 deletions(-)
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index af70d5086b7dc..62c53f1d8fbd1 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1524,25 +1524,26 @@ class Process : public std::enable_shared_from_this<Process>,
virtual FileSpec GetCoreFile() const { return {}; }
class CoreArgs {
- std::string cmd;
- bool might_be_truncated;
+ std::string m_cmd;
+ bool m_might_be_truncated;
public:
CoreArgs() = default;
CoreArgs(const std::string &args, bool might_be_truncated)
- : cmd(args), might_be_truncated(might_be_truncated) {}
-
- void Format(Stream &stream) {
- if (!cmd.empty()) {
- stream << "Core was generated by '" << cmd << "'";
- if (this->might_be_truncated)
- stream << " (command might be truncated)";
- stream << ".\n.";
- }
+ : m_cmd(args), m_might_be_truncated(might_be_truncated) {}
+
+ void Format(Stream &stream) const {
+ if (m_cmd.empty())
+ return;
+ stream << "Core was generated by '" << m_cmd << "'";
+ if (this->m_might_be_truncated)
+ stream << " (command might be truncated)";
+ stream << ".\n";
}
- bool empty() { return cmd.empty(); }
- Args as_args() { return Args(cmd); }
+ bool empty() const { return m_cmd.empty(); }
+
+ Args as_args() const { return Args(m_cmd); }
};
/// Provide arguments of a command that triggered a core dump.
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 6b029b6f13612..cc40c6cffe2c7 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -992,9 +992,12 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
sizeof(prpsinfo.pr_psargs)))
.str();
// pr_psargs's char array used to represent arguments is only 80 character
- // long
- // (\0 included), hence 79.
- m_process_args = CoreArgs(core_arg, core_arg.size() == 79);
+ // long (\0 included), for a total of 79.
+ // We set core_arg's m_might_be_truncated = true if its size
+ // is the maximum (79).
+ m_process_args =
+ CoreArgs(core_arg, /*might_be_truncated=*/core_arg.size() ==
+ sizeof(prpsinfo.pr_psargs) - 1);
break;
}
case ELF::NT_SIGINFO: {
@@ -1182,7 +1185,6 @@ bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) {
info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
add_exe_file_as_first_arg);
}
- if (!m_process_args.empty())
- info.SetArguments(m_process_args.as_args(), true);
+ info.SetArguments(m_process_args.as_args(), /*first_arg_is_executable=*/true);
return true;
}
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index da08071eec229..94b09a64bb309 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -5948,13 +5948,11 @@ void Process::GetStatus(Stream &strm, bool is_verbose) {
} else {
if (state == eStateConnected)
strm.Printf("Connected to remote target.\n");
- else if (!IsLiveDebugSession()) {
+ else {
strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
- auto core_args = GetCoreFileArgs();
- if (core_args && is_verbose)
+ if (auto core_args = GetCoreFileArgs(); core_args && is_verbose)
core_args->Format(strm);
- } else
- strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
+ }
}
} 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 50eb432d12ae9..959339c2c6ca0 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -61,7 +61,7 @@ def test_x86_64(self):
@skipIfLLVMTargetMissing("X86")
def test_x86_64_core_args_truncated(self):
"""Test that a truncated pr_psargs shows a truncation warning."""
- core_arg_msg = "Core was generated by '/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/tes' (command might be truncated)."
+ core_arg_msg = "\nCore was generated by '/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/tes' (command might be truncated).\n"
self.expect(
"target create linux-x86_64.out --core linux-x86_64.core",
msg="Truncated pr_psargs should show truncation warning when core file is loaded.",
@@ -82,8 +82,8 @@ def test_x86_64_core_args_truncated(self):
@skipIfLLVMTargetMissing("X86")
def test_x86_64_core_args_not_truncated(self):
"""Test that a short pr_psargs does not show a truncation warning."""
- core_arg_msg = "Core was generated by './a.out '."
- # This core file has pr_psargs='./a.out', which is short.
+ core_arg_msg = "\nCore was generated by './a.out '.\n"
+ # This core file has pr_psargs='./a.out ', which is short.
self.expect(
"target create --core linux-fpr_sse_x86_64.core",
msg="Short pr_psargs should show the core args without truncation warning when core file is loaded.",
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 91b150c9fe982..81cd4165bb684 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -235,6 +235,8 @@ Changes to LLDB
* On Arm Linux, the tpidruro register can now be read. Writing to this register is not supported.
* Thread local variables are now supported on Arm Linux if the program being debugged is using glibc.
+* When an ELF core file is loaded, LLDB now shows the command line that created the core file.
+ If you need to see it again, use the command process status -v.
Changes to BOLT
---------------
>From 0e3d0ebe04a91d4419350cba4e2913d3d64b71f7 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Fri, 17 Apr 2026 10:57:48 -0700
Subject: [PATCH 15/15] Remove missed conflict
---
llvm/docs/ReleaseNotes.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 955609e40fd94..50f28d36ff515 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -303,7 +303,6 @@ Changes to LLDB
### Windows
* Python 3.11 or later is now recommended for building LLDB 23 on Windows. From LLDB 24, Python 3.11 or later will be required.
->>>>>>> main
Changes to BOLT
---------------
More information about the lldb-commits
mailing list