aboutsummaryrefslogtreecommitdiff
path: root/lldb/source
diff options
context:
space:
mode:
authorMichał Górny <mgorny@moritz.systems>2021-04-26 13:47:02 +0200
committerMichał Górny <mgorny@moritz.systems>2021-09-06 12:16:14 +0200
commit37cbd817d3e2b8c673862e2eb262cad6dd3dd244 (patch)
tree57262d6e7bbc9c8d89a3a88be8887c0b64fee23d /lldb/source
parentfae0dfa6421ea6c02f86ba7292fa782e1e2b69d1 (diff)
downloadllvm-37cbd817d3e2b8c673862e2eb262cad6dd3dd244.zip
llvm-37cbd817d3e2b8c673862e2eb262cad6dd3dd244.tar.gz
llvm-37cbd817d3e2b8c673862e2eb262cad6dd3dd244.tar.bz2
[lldb] [llgs server] Support creating core dumps on NetBSD
Add a new SaveCore() process method that can be used to request a core dump. This is currently implemented on NetBSD via the PT_DUMPCORE ptrace(2) request, and enabled via 'savecore' extension. Protocol-wise, a new qSaveCore packet is introduced. It accepts zero or more semicolon-separated key:value options, invokes the core dump and returns a key:value response. Currently the only option supported is "path-hint", and the return value contains the "path" actually used. The support for the feature is exposed via qSaveCore qSupported feature. Differential Revision: https://reviews.llvm.org/D101285
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp27
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp41
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h2
-rw-r--r--lldb/source/Utility/StringExtractorGDBRemote.cpp2
5 files changed, 73 insertions, 1 deletions
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 9ea1a16..0420d00 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -136,7 +136,8 @@ NativeProcessNetBSD::Factory::Attach(
NativeProcessNetBSD::Extension
NativeProcessNetBSD::Factory::GetSupportedExtensions() const {
return Extension::multiprocess | Extension::fork | Extension::vfork |
- Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
+ Extension::pass_signals | Extension::auxv | Extension::libraries_svr4 |
+ Extension::savecore;
}
// Public Instance Methods
@@ -1073,3 +1074,27 @@ void NativeProcessNetBSD::MonitorClone(::pid_t child_pid, bool is_vfork,
}
}
}
+
+llvm::Expected<std::string>
+NativeProcessNetBSD::SaveCore(llvm::StringRef path_hint) {
+ llvm::SmallString<128> path{path_hint};
+ Status error;
+
+ // Try with the suggested path first.
+ if (!path.empty()) {
+ error = PtraceWrapper(PT_DUMPCORE, GetID(), path.data(), path.size());
+ if (!error.Fail())
+ return path.str().str();
+
+ // If the request errored, fall back to a generic temporary file.
+ }
+
+ if (std::error_code errc =
+ llvm::sys::fs::createTemporaryFile("lldb", "core", path))
+ return llvm::createStringError(errc, "Unable to create a temporary file");
+
+ error = PtraceWrapper(PT_DUMPCORE, GetID(), path.data(), path.size());
+ if (error.Fail())
+ return error.ToError();
+ return path.str().str();
+}
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index 90d32aa..3f54d02 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -88,6 +88,8 @@ public:
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
int data = 0, int *result = nullptr);
+ llvm::Expected<std::string> SaveCore(llvm::StringRef path_hint) override;
+
private:
MainLoop::SignalHandleUP m_sigchld_handle;
ArchSpec m_arch;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 8e1f6bc..5d0ce3a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -226,6 +226,10 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
quit = true;
return this->Handle_k(packet);
});
+
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qLLDBSaveCore,
+ &GDBRemoteCommunicationServerLLGS::Handle_qSaveCore);
}
void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &info) {
@@ -3604,6 +3608,41 @@ GDBRemoteCommunicationServerLLGS::Handle_QMemTags(
return status.Success() ? SendOKResponse() : SendErrorResponse(1);
}
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qSaveCore(
+ StringExtractorGDBRemote &packet) {
+ // Fail if we don't have a current process.
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(Status("Process not running."));
+
+ std::string path_hint;
+
+ StringRef packet_str{packet.GetStringRef()};
+ bool cf = packet_str.consume_front("qSaveCore");
+ assert(cf);
+ if (packet_str.consume_front(";")) {
+ llvm::SmallVector<llvm::StringRef, 2> fields;
+ packet_str.split(fields, ';');
+
+ for (auto x : fields) {
+ if (x.consume_front("path-hint:"))
+ StringExtractor(x).GetHexByteString(path_hint);
+ else
+ return SendErrorResponse(Status("Unsupported qSaveCore option"));
+ }
+ }
+
+ llvm::Expected<std::string> ret = m_current_process->SaveCore(path_hint);
+ if (!ret)
+ return SendErrorResponse(std::move(ret.takeError()));
+
+ StreamString response;
+ response.PutCString("core-path:");
+ response.PutStringAsRawHex8(ret.get());
+ return SendPacketNoLock(response.GetString());
+}
+
void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
@@ -3800,6 +3839,8 @@ std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures(
ret.push_back("qXfer:libraries-svr4:read+");
if (bool(plugin_features & Extension::memory_tagging))
ret.push_back("memory-tagging+");
+ if (bool(plugin_features & Extension::savecore))
+ ret.push_back("qSaveCore+");
// check for client features
m_extensions_supported = {};
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 04d0605..f054e37 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -214,6 +214,8 @@ protected:
PacketResult Handle_QPassSignals(StringExtractorGDBRemote &packet);
+ PacketResult Handle_qSaveCore(StringExtractorGDBRemote &packet);
+
PacketResult Handle_g(StringExtractorGDBRemote &packet);
PacketResult Handle_qMemTags(StringExtractorGDBRemote &packet);
diff --git a/lldb/source/Utility/StringExtractorGDBRemote.cpp b/lldb/source/Utility/StringExtractorGDBRemote.cpp
index 29cf585..7279075 100644
--- a/lldb/source/Utility/StringExtractorGDBRemote.cpp
+++ b/lldb/source/Utility/StringExtractorGDBRemote.cpp
@@ -260,6 +260,8 @@ StringExtractorGDBRemote::GetServerPacketType() const {
break;
case 'S':
+ if (PACKET_STARTS_WITH("qSaveCore"))
+ return eServerPacketType_qLLDBSaveCore;
if (PACKET_STARTS_WITH("qSpeedTest:"))
return eServerPacketType_qSpeedTest;
if (PACKET_MATCHES("qShlibInfoAddr"))