blob: 2259d52a8b28b482dda62d3600b963005f8c7897 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "garnet/bin/debug_agent/object_util.h"
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <lib/zx/thread.h>
#include <zircon/syscalls/object.h>
namespace debug_agent {
namespace {
template <typename ResultObject>
std::vector<ResultObject> GetChildObjects(zx_handle_t parent,
uint32_t child_kind) {
auto koids = GetChildKoids(parent, child_kind);
std::vector<ResultObject> result;
result.reserve(koids.size());
for (zx_koid_t koid : koids) {
zx_handle_t handle;
if (zx_object_get_child(parent, koid, ZX_RIGHT_SAME_RIGHTS, &handle) ==
ZX_OK)
result.push_back(ResultObject(handle));
}
return result;
}
} // namespace
zx::thread ThreadForKoid(zx_handle_t process, zx_koid_t thread_koid) {
zx_handle_t thread_handle = ZX_HANDLE_INVALID;
if (zx_object_get_child(process, thread_koid, ZX_RIGHT_SAME_RIGHTS,
&thread_handle) != ZX_OK)
return zx::thread();
return zx::thread(thread_handle);
}
zx_koid_t KoidForProcess(const zx::process& process) {
return KoidForObject(process.get());
}
zx_koid_t KoidForObject(zx_handle_t object) {
zx_info_handle_basic_t info;
if (zx_object_get_info(object, ZX_INFO_HANDLE_BASIC, &info, sizeof(info),
nullptr, nullptr) != ZX_OK)
return 0;
return info.koid;
}
std::string NameForObject(zx_handle_t object) {
char name[ZX_MAX_NAME_LEN];
if (zx_object_get_property(object, ZX_PROP_NAME, name, sizeof(name)) == ZX_OK)
return std::string(name);
return std::string();
}
std::vector<zx_koid_t> GetChildKoids(zx_handle_t parent, uint32_t child_kind) {
constexpr size_t kNumExtraKoids = 10u;
size_t actual = 0;
size_t available = 0;
std::vector<zx_koid_t> result;
// This is inherently racy, but we retry once with a bit of slop to try to
// get a complete list.
for (int pass = 0; pass < 2; pass++) {
if (actual < available)
result.resize(available + kNumExtraKoids);
zx_status_t status = zx_object_get_info(parent, child_kind, result.data(),
result.size() * sizeof(zx_koid_t),
&actual, &available);
if (status != ZX_OK || actual == available)
break;
}
result.resize(actual);
return result;
}
std::vector<zx::job> GetChildJobs(zx_handle_t job) {
return GetChildObjects<zx::job>(job, ZX_INFO_JOB_CHILDREN);
}
std::vector<zx::process> GetChildProcesses(zx_handle_t job) {
return GetChildObjects<zx::process>(job, ZX_INFO_JOB_PROCESSES);
}
std::vector<zx::thread> GetChildThreads(zx_handle_t process) {
return GetChildObjects<zx::thread>(process, ZX_INFO_PROCESS_THREADS);
}
} // namespace debug_agent