本文整理汇总了C++中ProcessLaunchInfo类的典型用法代码示例。如果您正苦于以下问题:C++ ProcessLaunchInfo类的具体用法?C++ ProcessLaunchInfo怎么用?C++ ProcessLaunchInfo使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了ProcessLaunchInfo类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: DisableASLRIfRequested
static void DisableASLRIfRequested(int error_fd, const ProcessLaunchInfo &info) {
#if defined(__linux__)
if (info.GetFlags().Test(lldb::eLaunchFlagDisableASLR)) {
const unsigned long personality_get_current = 0xffffffff;
int value = personality(personality_get_current);
if (value == -1)
ExitWithError(error_fd, "personality get");
value = personality(ADDR_NO_RANDOMIZE | value);
if (value == -1)
ExitWithError(error_fd, "personality set");
}
#endif
}
示例2: HostProcess
HostProcess
ProcessLauncherPosix::LaunchProcess(const ProcessLaunchInfo &launch_info,
Error &error) {
lldb::pid_t pid;
char exe_path[PATH_MAX];
launch_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
// TODO(zturner): Move the code from LaunchProcessPosixSpawn to here, and make
// MacOSX re-use this
// ProcessLauncher when it wants a posix_spawn launch.
error = Host::LaunchProcessPosixSpawn(exe_path, launch_info, pid);
return HostProcess(pid);
}
示例3: attach_info
ProcessSP
PlatformWindows::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, Target *target, Error &error)
{
// Windows has special considerations that must be followed when launching or attaching to a process. The
// key requirement is that when launching or attaching to a process, you must do it from the same the thread
// that will go into a permanent loop which will then receive debug events from the process. In particular,
// this means we can't use any of LLDB's generic mechanisms to do it for us, because it doesn't have the
// special knowledge required for setting up the background thread or passing the right flags.
//
// Another problem is that that LLDB's standard model for debugging a process is to first launch it, have
// it stop at the entry point, and then attach to it. In Windows this doesn't quite work, you have to
// specify as an argument to CreateProcess() that you're going to debug the process. So we override DebugProcess
// here to handle this. Launch operations go directly to the process plugin, and attach operations almost go
// directly to the process plugin (but we hijack the events first). In essence, we encapsulate all the logic
// of Launching and Attaching in the process plugin, and PlatformWindows::DebugProcess is just a pass-through
// to get to the process plugin.
if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
{
// This is a process attach. Don't need to launch anything.
ProcessAttachInfo attach_info(launch_info);
return Attach(attach_info, debugger, target, error);
}
else
{
ProcessSP process_sp = target->CreateProcess(launch_info.GetListenerForProcess(debugger),
launch_info.GetProcessPluginName(),
nullptr);
// We need to launch and attach to the process.
launch_info.GetFlags().Set(eLaunchFlagDebug);
if (process_sp)
error = process_sp->Launch(launch_info);
return process_sp;
}
}
示例4: Error
Error
PlatformLinux::LaunchNativeProcess (
ProcessLaunchInfo &launch_info,
lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
NativeProcessProtocolSP &process_sp)
{
#if !defined(__linux__)
return Error("only implemented on Linux hosts");
#else
if (!IsHost ())
return Error("PlatformLinux::%s (): cannot launch a debug process when not the host", __FUNCTION__);
// Retrieve the exe module.
lldb::ModuleSP exe_module_sp;
Error error = ResolveExecutable (
launch_info.GetExecutableFile (),
launch_info.GetArchitecture (),
exe_module_sp,
NULL);
if (!error.Success ())
return error;
if (!exe_module_sp)
return Error("exe_module_sp could not be resolved for %s", launch_info.GetExecutableFile ().GetPath ().c_str ());
// Launch it for debugging
error = NativeProcessLinux::LaunchProcess (
exe_module_sp.get (),
launch_info,
native_delegate,
process_sp);
return error;
#endif
}
示例5: WorkingDir
Error
ProcessPOSIX::DoLaunch (Module *module,
ProcessLaunchInfo &launch_info)
{
Error error;
assert(m_monitor == NULL);
const char* working_dir = launch_info.GetWorkingDirectory();
if (working_dir) {
FileSpec WorkingDir(working_dir, true);
if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory)
{
error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
return error;
}
}
SetPrivateState(eStateLaunching);
const lldb_private::FileAction *file_action;
// Default of NULL will mean to use existing open file descriptors
const char *stdin_path = NULL;
const char *stdout_path = NULL;
const char *stderr_path = NULL;
file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
stdin_path = GetFilePath(file_action, stdin_path);
file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
stdout_path = GetFilePath(file_action, stdout_path);
file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
stderr_path = GetFilePath(file_action, stderr_path);
m_monitor = new ProcessMonitor (this,
module,
launch_info.GetArguments().GetConstArgumentVector(),
launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
stdin_path,
stdout_path,
stderr_path,
working_dir,
launch_info,
error);
m_module = module;
if (!error.Success())
return error;
SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
SetID(m_monitor->GetPID());
return error;
}
示例6: slave_thread
Error
DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info)
{
WINLOG_IFALL(WINDOWS_LOG_PROCESS,
"DebuggerThread::DebugLaunch launching '%s'", launch_info.GetExecutableFile().GetPath().c_str());
Error error;
DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]",
DebuggerThreadLaunchRoutine, context, &error));
if (!error.Success())
{
WINERR_IFALL(WINDOWS_LOG_PROCESS,
"DebugLaunch couldn't launch debugger thread. %s", error.AsCString());
}
return error;
}
示例7: HostProcess
HostProcess
ProcessLauncherPosixFork::LaunchProcess(const ProcessLaunchInfo &launch_info,
Status &error) {
char exe_path[PATH_MAX];
launch_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
// A pipe used by the child process to report errors.
PipePosix pipe;
const bool child_processes_inherit = false;
error = pipe.CreateNew(child_processes_inherit);
if (error.Fail())
return HostProcess();
::pid_t pid = ::fork();
if (pid == -1) {
// Fork failed
error.SetErrorStringWithFormatv("Fork failed with error message: {0}",
llvm::sys::StrError());
return HostProcess(LLDB_INVALID_PROCESS_ID);
}
if (pid == 0) {
// child process
pipe.CloseReadFileDescriptor();
ChildFunc(pipe.ReleaseWriteFileDescriptor(), launch_info);
}
// parent process
pipe.CloseWriteFileDescriptor();
char buf[1000];
int r = read(pipe.GetReadFileDescriptor(), buf, sizeof buf);
if (r == 0)
return HostProcess(pid); // No error. We're done.
error.SetErrorString(buf);
llvm::sys::RetryAfterSignal(-1, waitpid, pid, nullptr, 0);
return HostProcess();
}
示例8: LaunchProcess
Error Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
std::unique_ptr<ProcessLauncher> delegate_launcher;
#if defined(_WIN32)
delegate_launcher.reset(new ProcessLauncherWindows());
#elif defined(__linux__)
delegate_launcher.reset(new ProcessLauncherLinux());
#else
delegate_launcher.reset(new ProcessLauncherPosix());
#endif
MonitoringProcessLauncher launcher(std::move(delegate_launcher));
Error error;
HostProcess process = launcher.LaunchProcess(launch_info, error);
// TODO(zturner): It would be better if the entire HostProcess were returned
// instead of writing
// it into this structure.
launch_info.SetProcessID(process.GetProcessId());
return error;
}
示例9: sigemptyset
Error
Host::LaunchProcessPosixSpawn(const char *exe_path, const ProcessLaunchInfo &launch_info, lldb::pid_t &pid)
{
Error error;
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
posix_spawnattr_t attr;
error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
if (error.Fail() || log)
error.PutToLog(log, "::posix_spawnattr_init ( &attr )");
if (error.Fail())
return error;
// Make a quick class that will cleanup the posix spawn attributes in case
// we return in the middle of this function.
lldb_utility::CleanUp <posix_spawnattr_t *, int> posix_spawnattr_cleanup(&attr, posix_spawnattr_destroy);
sigset_t no_signals;
sigset_t all_signals;
sigemptyset (&no_signals);
sigfillset (&all_signals);
::posix_spawnattr_setsigmask(&attr, &no_signals);
#if defined (__linux__) || defined (__FreeBSD__)
::posix_spawnattr_setsigdefault(&attr, &no_signals);
#else
::posix_spawnattr_setsigdefault(&attr, &all_signals);
#endif
short flags = GetPosixspawnFlags(launch_info);
error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX);
if (error.Fail() || log)
error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags);
if (error.Fail())
return error;
// posix_spawnattr_setbinpref_np appears to be an Apple extension per:
// http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/
#if defined (__APPLE__) && !defined (__arm__)
// Don't set the binpref if a shell was provided. After all, that's only going to affect what version of the shell
// is launched, not what fork of the binary is launched. We insert "arch --arch <ARCH> as part of the shell invocation
// to do that job on OSX.
if (launch_info.GetShell() == nullptr)
{
// We don't need to do this for ARM, and we really shouldn't now that we
// have multiple CPU subtypes and no posix_spawnattr call that allows us
// to set which CPU subtype to launch...
const ArchSpec &arch_spec = launch_info.GetArchitecture();
cpu_type_t cpu = arch_spec.GetMachOCPUType();
cpu_type_t sub = arch_spec.GetMachOCPUSubType();
if (cpu != 0 &&
cpu != static_cast<cpu_type_t>(UINT32_MAX) &&
cpu != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE) &&
!(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try to set the CPU type or we will fail
{
size_t ocount = 0;
error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX);
if (error.Fail() || log)
error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount);
if (error.Fail() || ocount != 1)
return error;
}
}
#endif
const char *tmp_argv[2];
char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector();
char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector();
if (argv == NULL)
{
// posix_spawn gets very unhappy if it doesn't have at least the program
// name in argv[0]. One of the side affects I have noticed is the environment
// variables don't make it into the child process if "argv == NULL"!!!
tmp_argv[0] = exe_path;
tmp_argv[1] = NULL;
argv = (char * const*)tmp_argv;
}
#if !defined (__APPLE__)
// manage the working directory
char current_dir[PATH_MAX];
current_dir[0] = '\0';
#endif
FileSpec working_dir{launch_info.GetWorkingDirectory()};
if (working_dir)
{
#if defined (__APPLE__)
// Set the working directory on this thread only
if (__pthread_chdir(working_dir.GetCString()) < 0) {
if (errno == ENOENT) {
error.SetErrorStringWithFormat("No such file or directory: %s",
working_dir.GetCString());
} else if (errno == ENOTDIR) {
error.SetErrorStringWithFormat("Path doesn't name a directory: %s",
//.........这里部分代码省略.........
示例10: ChildFunc
static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd,
const ProcessLaunchInfo &info) {
if (info.GetFlags().Test(eLaunchFlagLaunchInSeparateProcessGroup)) {
if (setpgid(0, 0) != 0)
ExitWithError(error_fd, "setpgid");
}
for (size_t i = 0; i < info.GetNumFileActions(); ++i) {
const FileAction &action = *info.GetFileActionAtIndex(i);
switch (action.GetAction()) {
case FileAction::eFileActionClose:
if (close(action.GetFD()) != 0)
ExitWithError(error_fd, "close");
break;
case FileAction::eFileActionDuplicate:
if (dup2(action.GetFD(), action.GetActionArgument()) == -1)
ExitWithError(error_fd, "dup2");
break;
case FileAction::eFileActionOpen:
DupDescriptor(error_fd, action.GetFileSpec(), action.GetFD(),
action.GetActionArgument());
break;
case FileAction::eFileActionNone:
break;
}
}
const char **argv = info.GetArguments().GetConstArgumentVector();
// Change working directory
if (info.GetWorkingDirectory() &&
0 != ::chdir(info.GetWorkingDirectory().GetCString()))
ExitWithError(error_fd, "chdir");
DisableASLRIfRequested(error_fd, info);
Environment env = info.GetEnvironment();
FixupEnvironment(env);
Environment::Envp envp = env.getEnvp();
// Clear the signal mask to prevent the child from being affected by any
// masking done by the parent.
sigset_t set;
if (sigemptyset(&set) != 0 ||
pthread_sigmask(SIG_SETMASK, &set, nullptr) != 0)
ExitWithError(error_fd, "pthread_sigmask");
if (info.GetFlags().Test(eLaunchFlagDebug)) {
// Do not inherit setgid powers.
if (setgid(getgid()) != 0)
ExitWithError(error_fd, "setgid");
// HACK:
// Close everything besides stdin, stdout, and stderr that has no file
// action to avoid leaking. Only do this when debugging, as elsewhere we
// actually rely on passing open descriptors to child processes.
for (int fd = 3; fd < sysconf(_SC_OPEN_MAX); ++fd)
if (!info.GetFileActionForFD(fd) && fd != error_fd)
close(fd);
// Start tracing this child that is about to exec.
if (ptrace(PT_TRACE_ME, 0, nullptr, 0) == -1)
ExitWithError(error_fd, "ptrace");
}
// Execute. We should never return...
execve(argv[0], const_cast<char *const *>(argv), envp);
#if defined(__linux__)
if (errno == ETXTBSY) {
// On android M and earlier we can get this error because the adb daemon
// can hold a write handle on the executable even after it has finished
// uploading it. This state lasts only a short time and happens only when
// there are many concurrent adb commands being issued, such as when
// running the test suite. (The file remains open when someone does an "adb
// shell" command in the fork() child before it has had a chance to exec.)
// Since this state should clear up quickly, wait a while and then give it
// one more go.
usleep(50000);
execve(argv[0], const_cast<char *const *>(argv), envp);
}
#endif
// ...unless exec fails. In which case we definitely need to end the child
// here.
ExitWithError(error_fd, "execve");
}
示例11: DebugProcess
// 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, NULL, 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).
//.........这里部分代码省略.........
示例12: WorkingDir
Error
ProcessPOSIX::DoLaunch (Module *module,
ProcessLaunchInfo &launch_info)
{
Error error;
assert(m_monitor == NULL);
const char* working_dir = launch_info.GetWorkingDirectory();
if (working_dir) {
FileSpec WorkingDir(working_dir, true);
if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory)
{
error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
return error;
}
}
SetPrivateState(eStateLaunching);
const lldb_private::FileAction *file_action;
// Default of NULL will mean to use existing open file descriptors
const char *stdin_path = NULL;
const char *stdout_path = NULL;
const char *stderr_path = NULL;
const char * dbg_pts_path = launch_info.GetPTY().GetSlaveName(NULL,0);
file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
stdin_path = GetFilePath(file_action, stdin_path, dbg_pts_path);
file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
stdout_path = GetFilePath(file_action, stdout_path, dbg_pts_path);
file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
stderr_path = GetFilePath(file_action, stderr_path, dbg_pts_path);
m_monitor = new ProcessMonitor (this,
module,
launch_info.GetArguments().GetConstArgumentVector(),
launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
stdin_path,
stdout_path,
stderr_path,
working_dir,
launch_info,
error);
m_module = module;
if (!error.Success())
return error;
int terminal = m_monitor->GetTerminalFD();
if (terminal >= 0) {
// The reader thread will close the file descriptor when done, so we pass it a copy.
int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0);
if (stdio == -1) {
error.SetErrorToErrno();
return error;
}
SetSTDIOFileDescriptor(stdio);
}
SetID(m_monitor->GetPID());
return error;
}
示例13: switch
Error
PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
Error error;
if (log)
log->Printf ("PlatformRemoteGDBServer::%s() called", __FUNCTION__);
auto num_file_actions = launch_info.GetNumFileActions ();
for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i)
{
const auto file_action = launch_info.GetFileActionAtIndex (i);
if (file_action->GetAction () != FileAction::eFileActionOpen)
continue;
switch(file_action->GetFD())
{
case STDIN_FILENO:
m_gdb_client.SetSTDIN(file_action->GetFileSpec());
break;
case STDOUT_FILENO:
m_gdb_client.SetSTDOUT(file_action->GetFileSpec());
break;
case STDERR_FILENO:
m_gdb_client.SetSTDERR(file_action->GetFileSpec());
break;
}
}
m_gdb_client.SetDisableASLR (launch_info.GetFlags().Test (eLaunchFlagDisableASLR));
m_gdb_client.SetDetachOnError (launch_info.GetFlags().Test (eLaunchFlagDetachOnError));
FileSpec working_dir = launch_info.GetWorkingDirectory();
if (working_dir)
{
m_gdb_client.SetWorkingDir(working_dir);
}
// Send the environment and the program + arguments after we connect
const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector();
if (envp)
{
const char *env_entry;
for (int i=0; (env_entry = envp[i]); ++i)
{
if (m_gdb_client.SendEnvironmentPacket(env_entry) != 0)
break;
}
}
ArchSpec arch_spec = launch_info.GetArchitecture();
const char *arch_triple = arch_spec.GetTriple().str().c_str();
m_gdb_client.SendLaunchArchPacket(arch_triple);
if (log)
log->Printf ("PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'", __FUNCTION__, arch_triple ? arch_triple : "<NULL>");
int arg_packet_err;
{
// Scope for the scoped timeout object
process_gdb_remote::GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_client, 5);
arg_packet_err = m_gdb_client.SendArgumentsPacket (launch_info);
}
if (arg_packet_err == 0)
{
std::string error_str;
if (m_gdb_client.GetLaunchSuccess (error_str))
{
const auto pid = m_gdb_client.GetCurrentProcessID (false);
if (pid != LLDB_INVALID_PROCESS_ID)
{
launch_info.SetProcessID (pid);
if (log)
log->Printf ("PlatformRemoteGDBServer::%s() pid %" PRIu64 " launched successfully", __FUNCTION__, pid);
}
else
{
if (log)
log->Printf ("PlatformRemoteGDBServer::%s() launch succeeded but we didn't get a valid process id back!", __FUNCTION__);
error.SetErrorString ("failed to get PID");
}
}
else
{
error.SetErrorString (error_str.c_str());
if (log)
log->Printf ("PlatformRemoteGDBServer::%s() launch failed: %s", __FUNCTION__, error.AsCString ());
}
}
else
{
error.SetErrorStringWithFormat("'A' packet returned an error: %i", arg_packet_err);
}
return error;
}
示例14: if
lldb::ProcessSP
PlatformRemoteGDBServer::DebugProcess (ProcessLaunchInfo &launch_info,
Debugger &debugger,
Target *target, // Can be NULL, if NULL create a new target, else use existing one
Error &error)
{
lldb::ProcessSP process_sp;
if (IsRemote())
{
if (IsConnected())
{
lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
uint16_t port = LaunchGDBserverAndGetPort(debugserver_pid);
if (port == 0)
{
error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ());
}
else
{
if (target == NULL)
{
TargetSP new_target_sp;
error = debugger.GetTargetList().CreateTarget (debugger,
NULL,
NULL,
false,
NULL,
new_target_sp);
target = new_target_sp.get();
}
else
error.Clear();
if (target && error.Success())
{
debugger.GetTargetList().SetSelectedTarget(target);
// The darwin always currently uses the GDB remote debugger plug-in
// so even when debugging locally we are debugging remotely!
process_sp = target->CreateProcess (launch_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
if (process_sp)
{
std::string connect_url =
MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port);
error = process_sp->ConnectRemote (nullptr, connect_url.c_str());
// Retry the connect remote one time...
if (error.Fail())
error = process_sp->ConnectRemote (nullptr, connect_url.c_str());
if (error.Success())
error = process_sp->Launch(launch_info);
else if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
{
printf ("error: connect remote failed (%s)\n", error.AsCString());
KillSpawnedProcess(debugserver_pid);
}
}
}
}
}
else
{
error.SetErrorString("not connected to remote gdb server");
}
}
return process_sp;
}
示例15: RunShellCommand
Error
Host::ShellExpandArguments (ProcessLaunchInfo &launch_info)
{
Error error;
if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments))
{
FileSpec expand_tool_spec;
if (!HostInfo::GetLLDBPath(lldb::ePathTypeSupportExecutableDir, expand_tool_spec))
{
error.SetErrorString("could not find argdumper tool");
return error;
}
expand_tool_spec.AppendPathComponent("argdumper.exe");
if (!expand_tool_spec.Exists())
{
error.SetErrorString("could not find argdumper tool");
return error;
}
std::string quoted_cmd_string;
launch_info.GetArguments().GetQuotedCommandString(quoted_cmd_string);
std::replace(quoted_cmd_string.begin(), quoted_cmd_string.end(), '\\', '/');
StreamString expand_command;
expand_command.Printf("%s %s",
expand_tool_spec.GetPath().c_str(),
quoted_cmd_string.c_str());
int status;
std::string output;
RunShellCommand(expand_command.GetData(), launch_info.GetWorkingDirectory(), &status, nullptr, &output, 10);
if (status != 0)
{
error.SetErrorStringWithFormat("argdumper exited with error %d", status);
return error;
}
auto data_sp = StructuredData::ParseJSON(output);
if (!data_sp)
{
error.SetErrorString("invalid JSON");
return error;
}
auto dict_sp = data_sp->GetAsDictionary();
if (!data_sp)
{
error.SetErrorString("invalid JSON");
return error;
}
auto args_sp = dict_sp->GetObjectForDotSeparatedPath("arguments");
if (!args_sp)
{
error.SetErrorString("invalid JSON");
return error;
}
auto args_array_sp = args_sp->GetAsArray();
if (!args_array_sp)
{
error.SetErrorString("invalid JSON");
return error;
}
launch_info.GetArguments().Clear();
for (size_t i = 0;
i < args_array_sp->GetSize();
i++)
{
auto item_sp = args_array_sp->GetItemAtIndex(i);
if (!item_sp)
continue;
auto str_sp = item_sp->GetAsString();
if (!str_sp)
continue;
launch_info.GetArguments().AppendArgument(str_sp->GetValue().c_str());
}
}
return error;
}