forked from OSchip/llvm-project
[lldb] [Platform] Move common ::DebugProcess() to PlatformPOSIX
Move common ::DebugProcess() implementation shared by Linux and NetBSD (and to be shared by FreeBSD shortly) into PlatformPOSIX, and move the old base implementation used only by Darwin to PlatformDarwin. Differential Revision: https://reviews.llvm.org/D88852
This commit is contained in:
parent
21100f885d
commit
a825eaa90e
|
@ -262,121 +262,6 @@ bool PlatformLinux::CanDebugProcess() {
|
|||
}
|
||||
}
|
||||
|
||||
// For local debugging, Linux will override the debug logic to use llgs-launch
|
||||
// rather than lldb-launch, llgs-attach. This differs from current lldb-
|
||||
// launch, debugserver-attach approach on MacOSX.
|
||||
lldb::ProcessSP
|
||||
PlatformLinux::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
|
||||
Target *target, // Can be NULL, if NULL create a new
|
||||
// target, else use existing one
|
||||
Status &error) {
|
||||
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
|
||||
LLDB_LOG(log, "target {0}", target);
|
||||
|
||||
// If we're a remote host, use standard behavior from parent class.
|
||||
if (!IsHost())
|
||||
return PlatformPOSIX::DebugProcess(launch_info, debugger, target, error);
|
||||
|
||||
//
|
||||
// For local debugging, we'll insist on having ProcessGDBRemote create the
|
||||
// process.
|
||||
//
|
||||
|
||||
ProcessSP process_sp;
|
||||
|
||||
// Make sure we stop at the entry point
|
||||
launch_info.GetFlags().Set(eLaunchFlagDebug);
|
||||
|
||||
// We always launch the process we are going to debug in a separate process
|
||||
// group, since then we can handle ^C interrupts ourselves w/o having to
|
||||
// worry about the target getting them as well.
|
||||
launch_info.SetLaunchInSeparateProcessGroup(true);
|
||||
|
||||
// Ensure we have a target.
|
||||
if (target == nullptr) {
|
||||
LLDB_LOG(log, "creating new target");
|
||||
TargetSP new_target_sp;
|
||||
error = debugger.GetTargetList().CreateTarget(
|
||||
debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
|
||||
if (error.Fail()) {
|
||||
LLDB_LOG(log, "failed to create new target: {0}", error);
|
||||
return process_sp;
|
||||
}
|
||||
|
||||
target = new_target_sp.get();
|
||||
if (!target) {
|
||||
error.SetErrorString("CreateTarget() returned nullptr");
|
||||
LLDB_LOG(log, "error: {0}", error);
|
||||
return process_sp;
|
||||
}
|
||||
}
|
||||
|
||||
// Mark target as currently selected target.
|
||||
debugger.GetTargetList().SetSelectedTarget(target);
|
||||
|
||||
// Now create the gdb-remote process.
|
||||
LLDB_LOG(log, "having target create process with gdb-remote plugin");
|
||||
process_sp =
|
||||
target->CreateProcess(launch_info.GetListener(), "gdb-remote", nullptr);
|
||||
|
||||
if (!process_sp) {
|
||||
error.SetErrorString("CreateProcess() failed for gdb-remote process");
|
||||
LLDB_LOG(log, "error: {0}", error);
|
||||
return process_sp;
|
||||
}
|
||||
|
||||
LLDB_LOG(log, "successfully created process");
|
||||
// Adjust launch for a hijacker.
|
||||
ListenerSP listener_sp;
|
||||
if (!launch_info.GetHijackListener()) {
|
||||
LLDB_LOG(log, "setting up hijacker");
|
||||
listener_sp =
|
||||
Listener::MakeListener("lldb.PlatformLinux.DebugProcess.hijack");
|
||||
launch_info.SetHijackListener(listener_sp);
|
||||
process_sp->HijackProcessEvents(listener_sp);
|
||||
}
|
||||
|
||||
// Log file actions.
|
||||
if (log) {
|
||||
LLDB_LOG(log, "launching process with the following file actions:");
|
||||
StreamString stream;
|
||||
size_t i = 0;
|
||||
const FileAction *file_action;
|
||||
while ((file_action = launch_info.GetFileActionAtIndex(i++)) != nullptr) {
|
||||
file_action->Dump(stream);
|
||||
LLDB_LOG(log, "{0}", stream.GetData());
|
||||
stream.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Do the launch.
|
||||
error = process_sp->Launch(launch_info);
|
||||
if (error.Success()) {
|
||||
// Handle the hijacking of process events.
|
||||
if (listener_sp) {
|
||||
const StateType state = process_sp->WaitForProcessToStop(
|
||||
llvm::None, nullptr, false, listener_sp);
|
||||
|
||||
LLDB_LOG(log, "pid {0} state {0}", process_sp->GetID(), state);
|
||||
}
|
||||
|
||||
// Hook up process PTY if we have one (which we should for local debugging
|
||||
// with llgs).
|
||||
int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
|
||||
if (pty_fd != PseudoTerminal::invalid_fd) {
|
||||
process_sp->SetSTDIOFileDescriptor(pty_fd);
|
||||
LLDB_LOG(log, "hooked up STDIO pty to process");
|
||||
} else
|
||||
LLDB_LOG(log, "not using process STDIO pty");
|
||||
} else {
|
||||
LLDB_LOG(log, "{0}", error);
|
||||
// FIXME figure out appropriate cleanup here. Do we delete the target? Do
|
||||
// we delete the process? Does our caller do that?
|
||||
}
|
||||
|
||||
return process_sp;
|
||||
}
|
||||
|
||||
void PlatformLinux::CalculateTrapHandlerSymbolNames() {
|
||||
m_trap_handlers.push_back(ConstString("_sigtramp"));
|
||||
m_trap_handlers.push_back(ConstString("__kernel_rt_sigreturn"));
|
||||
|
|
|
@ -48,10 +48,6 @@ public:
|
|||
|
||||
bool CanDebugProcess() override;
|
||||
|
||||
lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info,
|
||||
Debugger &debugger, Target *target,
|
||||
Status &error) override;
|
||||
|
||||
void CalculateTrapHandlerSymbolNames() override;
|
||||
|
||||
MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr,
|
||||
|
|
|
@ -1226,6 +1226,33 @@ PlatformDarwin::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
lldb::ProcessSP
|
||||
PlatformDarwin::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
|
||||
Target *target, // Can be NULL, if NULL create
|
||||
// a new target, else use existing
|
||||
// one
|
||||
Status &error) {
|
||||
ProcessSP process_sp;
|
||||
|
||||
if (IsHost()) {
|
||||
// We are going to hand this process off to debugserver which will be in
|
||||
// charge of setting the exit status. However, we still need to reap it
|
||||
// from lldb. So, make sure we use a exit callback which does not set exit
|
||||
// status.
|
||||
const bool monitor_signals = false;
|
||||
launch_info.SetMonitorProcessCallback(
|
||||
&ProcessLaunchInfo::NoOpMonitorCallback, monitor_signals);
|
||||
process_sp = Platform::DebugProcess(launch_info, debugger, target, error);
|
||||
} else {
|
||||
if (m_remote_platform_sp)
|
||||
process_sp = m_remote_platform_sp->DebugProcess(launch_info, debugger,
|
||||
target, error);
|
||||
else
|
||||
error.SetErrorString("the platform is not currently connected");
|
||||
}
|
||||
return process_sp;
|
||||
}
|
||||
|
||||
void PlatformDarwin::CalculateTrapHandlerSymbolNames() {
|
||||
m_trap_handlers.push_back(ConstString("_sigtramp"));
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "Plugins/Platform/POSIX/PlatformPOSIX.h"
|
||||
#include "lldb/Host/FileSystem.h"
|
||||
#include "lldb/Host/ProcessLaunchInfo.h"
|
||||
#include "lldb/Utility/ConstString.h"
|
||||
#include "lldb/Utility/FileSpec.h"
|
||||
#include "lldb/Utility/StructuredData.h"
|
||||
|
@ -68,6 +69,11 @@ public:
|
|||
int32_t GetResumeCountForLaunchInfo(
|
||||
lldb_private::ProcessLaunchInfo &launch_info) override;
|
||||
|
||||
lldb::ProcessSP DebugProcess(lldb_private::ProcessLaunchInfo &launch_info,
|
||||
lldb_private::Debugger &debugger,
|
||||
lldb_private::Target *target,
|
||||
lldb_private::Status &error) override;
|
||||
|
||||
void CalculateTrapHandlerSymbolNames() override;
|
||||
|
||||
llvm::VersionTuple
|
||||
|
|
|
@ -231,121 +231,6 @@ bool PlatformNetBSD::CanDebugProcess() {
|
|||
}
|
||||
}
|
||||
|
||||
// For local debugging, NetBSD will override the debug logic to use llgs-launch
|
||||
// rather than lldb-launch, llgs-attach. This differs from current lldb-
|
||||
// launch, debugserver-attach approach on MacOSX.
|
||||
lldb::ProcessSP
|
||||
PlatformNetBSD::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
|
||||
Target *target, // Can be NULL, if NULL create a new
|
||||
// target, else use existing one
|
||||
Status &error) {
|
||||
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
|
||||
LLDB_LOG(log, "target {0}", target);
|
||||
|
||||
// If we're a remote host, use standard behavior from parent class.
|
||||
if (!IsHost())
|
||||
return PlatformPOSIX::DebugProcess(launch_info, debugger, target, error);
|
||||
|
||||
//
|
||||
// For local debugging, we'll insist on having ProcessGDBRemote create the
|
||||
// process.
|
||||
//
|
||||
|
||||
ProcessSP process_sp;
|
||||
|
||||
// Make sure we stop at the entry point
|
||||
launch_info.GetFlags().Set(eLaunchFlagDebug);
|
||||
|
||||
// We always launch the process we are going to debug in a separate process
|
||||
// group, since then we can handle ^C interrupts ourselves w/o having to
|
||||
// worry about the target getting them as well.
|
||||
launch_info.SetLaunchInSeparateProcessGroup(true);
|
||||
|
||||
// Ensure we have a target.
|
||||
if (target == nullptr) {
|
||||
LLDB_LOG(log, "creating new target");
|
||||
TargetSP new_target_sp;
|
||||
error = debugger.GetTargetList().CreateTarget(
|
||||
debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
|
||||
if (error.Fail()) {
|
||||
LLDB_LOG(log, "failed to create new target: {0}", error);
|
||||
return process_sp;
|
||||
}
|
||||
|
||||
target = new_target_sp.get();
|
||||
if (!target) {
|
||||
error.SetErrorString("CreateTarget() returned nullptr");
|
||||
LLDB_LOG(log, "error: {0}", error);
|
||||
return process_sp;
|
||||
}
|
||||
}
|
||||
|
||||
// Mark target as currently selected target.
|
||||
debugger.GetTargetList().SetSelectedTarget(target);
|
||||
|
||||
// Now create the gdb-remote process.
|
||||
LLDB_LOG(log, "having target create process with gdb-remote plugin");
|
||||
process_sp =
|
||||
target->CreateProcess(launch_info.GetListener(), "gdb-remote", nullptr);
|
||||
|
||||
if (!process_sp) {
|
||||
error.SetErrorString("CreateProcess() failed for gdb-remote process");
|
||||
LLDB_LOG(log, "error: {0}", error);
|
||||
return process_sp;
|
||||
}
|
||||
|
||||
LLDB_LOG(log, "successfully created process");
|
||||
// Adjust launch for a hijacker.
|
||||
ListenerSP listener_sp;
|
||||
if (!launch_info.GetHijackListener()) {
|
||||
LLDB_LOG(log, "setting up hijacker");
|
||||
listener_sp =
|
||||
Listener::MakeListener("lldb.PlatformNetBSD.DebugProcess.hijack");
|
||||
launch_info.SetHijackListener(listener_sp);
|
||||
process_sp->HijackProcessEvents(listener_sp);
|
||||
}
|
||||
|
||||
// Log file actions.
|
||||
if (log) {
|
||||
LLDB_LOG(log, "launching process with the following file actions:");
|
||||
StreamString stream;
|
||||
size_t i = 0;
|
||||
const FileAction *file_action;
|
||||
while ((file_action = launch_info.GetFileActionAtIndex(i++)) != nullptr) {
|
||||
file_action->Dump(stream);
|
||||
LLDB_LOG(log, "{0}", stream.GetData());
|
||||
stream.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Do the launch.
|
||||
error = process_sp->Launch(launch_info);
|
||||
if (error.Success()) {
|
||||
// Handle the hijacking of process events.
|
||||
if (listener_sp) {
|
||||
const StateType state = process_sp->WaitForProcessToStop(
|
||||
llvm::None, nullptr, false, listener_sp);
|
||||
|
||||
LLDB_LOG(log, "pid {0} state {0}", process_sp->GetID(), state);
|
||||
}
|
||||
|
||||
// Hook up process PTY if we have one (which we should for local debugging
|
||||
// with llgs).
|
||||
int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
|
||||
if (pty_fd != PseudoTerminal::invalid_fd) {
|
||||
process_sp->SetSTDIOFileDescriptor(pty_fd);
|
||||
LLDB_LOG(log, "hooked up STDIO pty to process");
|
||||
} else
|
||||
LLDB_LOG(log, "not using process STDIO pty");
|
||||
} else {
|
||||
LLDB_LOG(log, "{0}", error);
|
||||
// FIXME figure out appropriate cleanup here. Do we delete the target? Do
|
||||
// we delete the process? Does our caller do that?
|
||||
}
|
||||
|
||||
return process_sp;
|
||||
}
|
||||
|
||||
void PlatformNetBSD::CalculateTrapHandlerSymbolNames() {
|
||||
m_trap_handlers.push_back(ConstString("_sigtramp"));
|
||||
}
|
||||
|
|
|
@ -48,10 +48,6 @@ public:
|
|||
|
||||
bool CanDebugProcess() override;
|
||||
|
||||
lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info,
|
||||
Debugger &debugger, Target *target,
|
||||
Status &error) override;
|
||||
|
||||
void CalculateTrapHandlerSymbolNames() override;
|
||||
|
||||
MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr,
|
||||
|
|
|
@ -416,24 +416,115 @@ PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
|
|||
Target *target, // Can be NULL, if NULL create a new
|
||||
// target, else use existing one
|
||||
Status &error) {
|
||||
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
|
||||
LLDB_LOG(log, "target {0}", target);
|
||||
|
||||
ProcessSP process_sp;
|
||||
|
||||
if (IsHost()) {
|
||||
// We are going to hand this process off to debugserver which will be in
|
||||
// charge of setting the exit status. However, we still need to reap it
|
||||
// from lldb. So, make sure we use a exit callback which does not set exit
|
||||
// status.
|
||||
const bool monitor_signals = false;
|
||||
launch_info.SetMonitorProcessCallback(
|
||||
&ProcessLaunchInfo::NoOpMonitorCallback, monitor_signals);
|
||||
process_sp = Platform::DebugProcess(launch_info, debugger, target, error);
|
||||
} else {
|
||||
if (!IsHost()) {
|
||||
if (m_remote_platform_sp)
|
||||
process_sp = m_remote_platform_sp->DebugProcess(launch_info, debugger,
|
||||
target, error);
|
||||
else
|
||||
error.SetErrorString("the platform is not currently connected");
|
||||
return process_sp;
|
||||
}
|
||||
|
||||
//
|
||||
// For local debugging, we'll insist on having ProcessGDBRemote create the
|
||||
// process.
|
||||
//
|
||||
|
||||
// Make sure we stop at the entry point
|
||||
launch_info.GetFlags().Set(eLaunchFlagDebug);
|
||||
|
||||
// We always launch the process we are going to debug in a separate process
|
||||
// group, since then we can handle ^C interrupts ourselves w/o having to
|
||||
// worry about the target getting them as well.
|
||||
launch_info.SetLaunchInSeparateProcessGroup(true);
|
||||
|
||||
// Ensure we have a target.
|
||||
if (target == nullptr) {
|
||||
LLDB_LOG(log, "creating new target");
|
||||
TargetSP new_target_sp;
|
||||
error = debugger.GetTargetList().CreateTarget(
|
||||
debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
|
||||
if (error.Fail()) {
|
||||
LLDB_LOG(log, "failed to create new target: {0}", error);
|
||||
return process_sp;
|
||||
}
|
||||
|
||||
target = new_target_sp.get();
|
||||
if (!target) {
|
||||
error.SetErrorString("CreateTarget() returned nullptr");
|
||||
LLDB_LOG(log, "error: {0}", error);
|
||||
return process_sp;
|
||||
}
|
||||
}
|
||||
|
||||
// Mark target as currently selected target.
|
||||
debugger.GetTargetList().SetSelectedTarget(target);
|
||||
|
||||
// Now create the gdb-remote process.
|
||||
LLDB_LOG(log, "having target create process with gdb-remote plugin");
|
||||
process_sp =
|
||||
target->CreateProcess(launch_info.GetListener(), "gdb-remote", nullptr);
|
||||
|
||||
if (!process_sp) {
|
||||
error.SetErrorString("CreateProcess() failed for gdb-remote process");
|
||||
LLDB_LOG(log, "error: {0}", error);
|
||||
return process_sp;
|
||||
}
|
||||
|
||||
LLDB_LOG(log, "successfully created process");
|
||||
// Adjust launch for a hijacker.
|
||||
ListenerSP listener_sp;
|
||||
if (!launch_info.GetHijackListener()) {
|
||||
LLDB_LOG(log, "setting up hijacker");
|
||||
listener_sp =
|
||||
Listener::MakeListener("lldb.PlatformLinux.DebugProcess.hijack");
|
||||
launch_info.SetHijackListener(listener_sp);
|
||||
process_sp->HijackProcessEvents(listener_sp);
|
||||
}
|
||||
|
||||
// Log file actions.
|
||||
if (log) {
|
||||
LLDB_LOG(log, "launching process with the following file actions:");
|
||||
StreamString stream;
|
||||
size_t i = 0;
|
||||
const FileAction *file_action;
|
||||
while ((file_action = launch_info.GetFileActionAtIndex(i++)) != nullptr) {
|
||||
file_action->Dump(stream);
|
||||
LLDB_LOG(log, "{0}", stream.GetData());
|
||||
stream.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Do the launch.
|
||||
error = process_sp->Launch(launch_info);
|
||||
if (error.Success()) {
|
||||
// Handle the hijacking of process events.
|
||||
if (listener_sp) {
|
||||
const StateType state = process_sp->WaitForProcessToStop(
|
||||
llvm::None, nullptr, false, listener_sp);
|
||||
|
||||
LLDB_LOG(log, "pid {0} state {0}", process_sp->GetID(), state);
|
||||
}
|
||||
|
||||
// Hook up process PTY if we have one (which we should for local debugging
|
||||
// with llgs).
|
||||
int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
|
||||
if (pty_fd != PseudoTerminal::invalid_fd) {
|
||||
process_sp->SetSTDIOFileDescriptor(pty_fd);
|
||||
LLDB_LOG(log, "hooked up STDIO pty to process");
|
||||
} else
|
||||
LLDB_LOG(log, "not using process STDIO pty");
|
||||
} else {
|
||||
LLDB_LOG(log, "{0}", error);
|
||||
// FIXME figure out appropriate cleanup here. Do we delete the target? Do
|
||||
// we delete the process? Does our caller do that?
|
||||
}
|
||||
|
||||
return process_sp;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue