[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
Tue Mar 31 23:52:14 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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.";
}
More information about the lldb-commits
mailing list