예제 #1
0
static bool
GetNetBSDProcessArgs (const ProcessInstanceInfoMatch *match_info_ptr,
                      ProcessInstanceInfo &process_info)
{
    if (!process_info.ProcessIDIsValid())
        return false;

    int pid = process_info.GetProcessID();

    int mib[4] = { CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV };

    char arg_data[8192];
    size_t arg_data_size = sizeof(arg_data);
    if (::sysctl (mib, 4, arg_data, &arg_data_size , NULL, 0) != 0)
        return false;

    DataExtractor data (arg_data, arg_data_size, lldb::endian::InlHostByteOrder(), sizeof(void *));
    lldb::offset_t offset = 0;
    const char *cstr;

    cstr = data.GetCStr (&offset);
    if (!cstr)
        return false;

    process_info.GetExecutableFile().SetFile(cstr, false);

    if (!(match_info_ptr == NULL ||
            NameMatches (process_info.GetExecutableFile().GetFilename().GetCString(),
                         match_info_ptr->GetNameMatchType(),
                         match_info_ptr->GetProcessInfo().GetName())))
        return false;

    Args &proc_args = process_info.GetArguments();
    while (1)
    {
        const uint8_t *p = data.PeekData(offset, 1);
        while ((p != NULL) && (*p == '\0') && offset < arg_data_size)
        {
            ++offset;
            p = data.PeekData(offset, 1);
        }
        if (p == NULL || offset >= arg_data_size)
            break;

        cstr = data.GetCStr(&offset);
        if (!cstr)
            break;

        proc_args.AppendArgument(cstr);
    }

    return true;
}
void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse(
    const ProcessInstanceInfo &proc_info, StreamString &response) {
  response.Printf(
      "pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
      proc_info.GetProcessID(), proc_info.GetParentProcessID(),
      proc_info.GetUserID(), proc_info.GetGroupID(),
      proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());
  response.PutCString("name:");
  response.PutCStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
  response.PutChar(';');
  const ArchSpec &proc_arch = proc_info.GetArchitecture();
  if (proc_arch.IsValid()) {
    const llvm::Triple &proc_triple = proc_arch.GetTriple();
    response.PutCString("triple:");
    response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
    response.PutChar(';');
  }
}
static bool
GetProcessAndStatInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info, ProcessStatInfo &stat_info, lldb::pid_t &tracerpid)
{
    tracerpid = 0;
    process_info.Clear();
    ::memset (&stat_info, 0, sizeof(stat_info));
    stat_info.ppid = LLDB_INVALID_PROCESS_ID;

    // Use special code here because proc/[pid]/exe is a symbolic link.
    char link_path[PATH_MAX];
    char exe_path[PATH_MAX] = "";
    if (snprintf (link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", pid) <= 0)
        return false;

    ssize_t len = readlink (link_path, exe_path, sizeof(exe_path) - 1);
    if (len <= 0)
        return false;

    // readlink does not append a null byte.
    exe_path[len] = 0;

    // If the binary has been deleted, the link name has " (deleted)" appended.
    //  Remove if there.
    static const ssize_t deleted_len = strlen(" (deleted)");
    if (len > deleted_len &&
        !strcmp(exe_path + len - deleted_len, " (deleted)"))
    {
        exe_path[len - deleted_len] = 0;
    }
    else
    {
        GetELFProcessCPUType (exe_path, process_info);
    }

    process_info.SetProcessID(pid);
    process_info.GetExecutableFile().SetFile(exe_path, false);

    lldb::DataBufferSP buf_sp;

    // Get the process environment.
    buf_sp = ReadProcPseudoFile(pid, "environ");
    Args &info_env = process_info.GetEnvironmentEntries();
    char *next_var = (char *)buf_sp->GetBytes();
    char *end_buf = next_var + buf_sp->GetByteSize();
    while (next_var < end_buf && 0 != *next_var)
    {
        info_env.AppendArgument(next_var);
        next_var += strlen(next_var) + 1;
    }

    // Get the commond line used to start the process.
    buf_sp = ReadProcPseudoFile(pid, "cmdline");

    // Grab Arg0 first.
    char *cmd = (char *)buf_sp->GetBytes();
    process_info.SetArg0(cmd);

    // Now process any remaining arguments.
    Args &info_args = process_info.GetArguments();
    char *next_arg = cmd + strlen(cmd) + 1;
    end_buf = cmd + buf_sp->GetByteSize();
    while (next_arg < end_buf && 0 != *next_arg)
    {
        info_args.AppendArgument(next_arg);
        next_arg += strlen(next_arg) + 1;
    }

    // Read /proc/$PID/stat to get our parent pid.
    if (ReadProcPseudoFileStat (pid, stat_info))
    {
        process_info.SetParentProcessID (stat_info.ppid);
    }

    // Get User and Group IDs and get tracer pid.
    GetLinuxProcessUserAndGroup (pid, process_info, tracerpid);

    return true;
}
예제 #4
0
파일: Host.cpp 프로젝트: emaste/lldb
static bool GetProcessAndStatInfo(::pid_t pid,
                                  ProcessInstanceInfo &process_info,
                                  ProcessState &State, ::pid_t &tracerpid) {
  tracerpid = 0;
  process_info.Clear();

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  // We can't use getProcFile here because proc/[pid]/exe is a symbolic link.
  llvm::SmallString<64> ProcExe;
  (llvm::Twine("/proc/") + llvm::Twine(pid) + "/exe").toVector(ProcExe);
  std::string ExePath(PATH_MAX, '\0');

  ssize_t len = readlink(ProcExe.c_str(), &ExePath[0], PATH_MAX);
  if (len <= 0) {
    LLDB_LOG(log, "failed to read link exe link for {0}: {1}", pid,
             Status(errno, eErrorTypePOSIX));
    return false;
  }
  ExePath.resize(len);

  // If the binary has been deleted, the link name has " (deleted)" appended.
  // Remove if there.
  llvm::StringRef PathRef = ExePath;
  PathRef.consume_back(" (deleted)");

  GetELFProcessCPUType(PathRef, process_info);

  // Get the process environment.
  auto BufferOrError = getProcFile(pid, "environ");
  if (!BufferOrError)
    return false;
  std::unique_ptr<llvm::MemoryBuffer> Environ = std::move(*BufferOrError);

  // Get the command line used to start the process.
  BufferOrError = getProcFile(pid, "cmdline");
  if (!BufferOrError)
    return false;
  std::unique_ptr<llvm::MemoryBuffer> Cmdline = std::move(*BufferOrError);

  // Get User and Group IDs and get tracer pid.
  if (!GetStatusInfo(pid, process_info, State, tracerpid))
    return false;

  process_info.SetProcessID(pid);
  process_info.GetExecutableFile().SetFile(PathRef, false);
  process_info.GetArchitecture().MergeFrom(HostInfo::GetArchitecture());

  llvm::StringRef Rest = Environ->getBuffer();
  while (!Rest.empty()) {
    llvm::StringRef Var;
    std::tie(Var, Rest) = Rest.split('\0');
    process_info.GetEnvironmentEntries().AppendArgument(Var);
  }

  llvm::StringRef Arg0;
  std::tie(Arg0, Rest) = Cmdline->getBuffer().split('\0');
  process_info.SetArg0(Arg0);
  while (!Rest.empty()) {
    llvm::StringRef Arg;
    std::tie(Arg, Rest) = Rest.split('\0');
    process_info.GetArguments().AppendArgument(Arg);
  }

  return true;
}