本文整理汇总了C++中ProcessLaunchInfo::GetFileActionAtIndex方法的典型用法代码示例。如果您正苦于以下问题:C++ ProcessLaunchInfo::GetFileActionAtIndex方法的具体用法?C++ ProcessLaunchInfo::GetFileActionAtIndex怎么用?C++ ProcessLaunchInfo::GetFileActionAtIndex使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ProcessLaunchInfo
的用法示例。
在下文中一共展示了ProcessLaunchInfo::GetFileActionAtIndex方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: sigemptyset
//.........这里部分代码省略.........
error.SetErrorStringWithFormat("Path doesn't name a directory: %s",
working_dir.GetCString());
} else {
error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution.");
}
return error;
}
#else
if (::getcwd(current_dir, sizeof(current_dir)) == NULL)
{
error.SetError(errno, eErrorTypePOSIX);
error.LogIfError(log, "unable to save the current directory");
return error;
}
if (::chdir(working_dir.GetCString()) == -1)
{
error.SetError(errno, eErrorTypePOSIX);
error.LogIfError(log, "unable to change working directory to %s",
working_dir.GetCString());
return error;
}
#endif
}
::pid_t result_pid = LLDB_INVALID_PROCESS_ID;
const size_t num_file_actions = launch_info.GetNumFileActions ();
if (num_file_actions > 0)
{
posix_spawn_file_actions_t file_actions;
error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
if (error.Fail() || log)
error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )");
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_spawn_file_actions_t *, int> posix_spawn_file_actions_cleanup (&file_actions, posix_spawn_file_actions_destroy);
for (size_t i=0; i<num_file_actions; ++i)
{
const FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i);
if (launch_file_action)
{
if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log, error))
return error;
}
}
error.SetError(::posix_spawnp(&result_pid, exe_path, &file_actions, &attr, argv, envp), eErrorTypePOSIX);
if (error.Fail() || log)
{
error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", result_pid,
exe_path, static_cast<void *>(&file_actions), static_cast<void *>(&attr), reinterpret_cast<const void *>(argv),
reinterpret_cast<const void *>(envp));
if (log)
{
for (int ii=0; argv[ii]; ++ii)
log->Printf("argv[%i] = '%s'", ii, argv[ii]);
}
}
}
else
{
error.SetError(::posix_spawnp(&result_pid, exe_path, NULL, &attr, argv, envp), eErrorTypePOSIX);
if (error.Fail() || log)
{
error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )",
result_pid, exe_path, static_cast<void *>(&attr), reinterpret_cast<const void *>(argv),
reinterpret_cast<const void *>(envp));
if (log)
{
for (int ii=0; argv[ii]; ++ii)
log->Printf("argv[%i] = '%s'", ii, argv[ii]);
}
}
}
pid = result_pid;
if (working_dir)
{
#if defined (__APPLE__)
// No more thread specific current working directory
__pthread_fchdir (-1);
#else
if (::chdir(current_dir) == -1 && error.Success())
{
error.SetError(errno, eErrorTypePOSIX);
error.LogIfError(log, "unable to change current directory back to %s",
current_dir);
}
#endif
}
return error;
}
示例2: 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");
}
示例3: 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;
}
示例4: DebugProcess
//.........这里部分代码省略.........
// Mark target as currently selected target.
debugger.GetTargetList().SetSelectedTarget(target);
// Now create the gdb-remote process.
if (log)
log->Printf ("PlatformLinux::%s having target create process with gdb-remote plugin", __FUNCTION__);
process_sp = target->CreateProcess (launch_info.GetListenerForProcess(debugger), "gdb-remote", nullptr);
if (!process_sp)
{
error.SetErrorString ("CreateProcess() failed for gdb-remote process");
if (log)
log->Printf ("PlatformLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
return process_sp;
}
else
{
if (log)
log->Printf ("PlatformLinux::%s successfully created process", __FUNCTION__);
}
// Set the unix signals properly.
process_sp->SetUnixSignals (Host::GetUnixSignals ());
// Adjust launch for a hijacker.
ListenerSP listener_sp;
if (!launch_info.GetHijackListener ())
{
if (log)
log->Printf ("PlatformLinux::%s setting up hijacker", __FUNCTION__);
listener_sp.reset (new Listener("lldb.PlatformLinux.DebugProcess.hijack"));
launch_info.SetHijackListener (listener_sp);
process_sp->HijackProcessEvents (listener_sp.get ());
}
// Log file actions.
if (log)
{
log->Printf ("PlatformLinux::%s launching process with the following file actions:", __FUNCTION__);
StreamString stream;
size_t i = 0;
const FileAction *file_action;
while ((file_action = launch_info.GetFileActionAtIndex (i++)) != nullptr)
{
file_action->Dump (stream);
log->PutCString (stream.GetString().c_str ());
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 (NULL, NULL, false, listener_sp.get());
process_sp->RestoreProcessEvents();
if (state == eStateStopped)
{
if (log)
log->Printf ("PlatformLinux::%s pid %" PRIu64 " state %s\n",
__FUNCTION__, process_sp->GetID (), StateAsCString (state));
}
else
{
if (log)
log->Printf ("PlatformLinux::%s pid %" PRIu64 " state is not stopped - %s\n",
__FUNCTION__, process_sp->GetID (), StateAsCString (state));
}
}
// Hook up process PTY if we have one (which we should for local debugging with llgs).
int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
{
process_sp->SetSTDIOFileDescriptor(pty_fd);
if (log)
log->Printf ("PlatformLinux::%s pid %" PRIu64 " hooked up STDIO pty to process", __FUNCTION__, process_sp->GetID ());
}
else
{
if (log)
log->Printf ("PlatformLinux::%s pid %" PRIu64 " not using process STDIO pty", __FUNCTION__, process_sp->GetID ());
}
}
else
{
if (log)
log->Printf ("PlatformLinux::%s process launch failed: %s", __FUNCTION__, error.AsCString ());
// FIXME figure out appropriate cleanup here. Do we delete the target? Do we delete the process? Does our caller do that?
}
return process_sp;
}
示例5: ChildFunc
static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd,
const ProcessLaunchInfo &info) {
// First, make sure we disable all logging. If we are logging to stdout, our
// logs can be
// mistaken for inferior output.
Log::DisableAllLogChannels(nullptr);
// Do not inherit setgid powers.
if (setgid(getgid()) != 0)
ExitWithError(error_fd, "setgid");
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");
// Disable ASLR if requested.
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");
}
Args env = info.GetEnvironmentEntries();
FixupEnvironment(env);
const char **envp = env.GetConstArgumentVector();
// 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)) {
// 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(PTRACE_TRACEME, 0, nullptr, nullptr) == -1)
ExitWithError(error_fd, "ptrace");
}
// Execute. We should never return...
execve(argv[0], const_cast<char *const *>(argv),
const_cast<char *const *>(envp));
if (errno == ETXTBSY) {
// On android M and earlier we can get this error because the adb deamon 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),
//.........这里部分代码省略.........
示例6: 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).
//.........这里部分代码省略.........