blob: 3f006772d10eaedadf7d2968fe16cc1d28ad640e [file] [log] [blame]
// Copyright 2022 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 "src/developer/process_explorer/utils.h"
#include <unordered_map>
#include "third_party/rapidjson/include/rapidjson/document.h"
#include "third_party/rapidjson/include/rapidjson/rapidjson.h"
#include "third_party/rapidjson/include/rapidjson/stringbuffer.h"
#include "third_party/rapidjson/include/rapidjson/writer.h"
namespace process_explorer {
std::string WriteProcessesDataAsJson(std::vector<Process> processes_data) {
rapidjson::Document json_document;
json_document.SetObject();
auto& allocator = json_document.GetAllocator();
rapidjson::Value processes_json(rapidjson::kArrayType);
processes_json.Reserve((unsigned int)processes_data.size(), allocator);
for (const auto& process : processes_data) {
rapidjson::Value process_objects_json(rapidjson::kArrayType);
process_objects_json.Reserve((unsigned int)process.objects.size(), allocator);
for (const auto& object : process.objects) {
rapidjson::Value object_json(rapidjson::kObjectType);
object_json.AddMember("object_type", object.object_type, allocator)
.AddMember("koid", object.koid, allocator)
.AddMember("related_koid", object.related_koid, allocator)
.AddMember("peer_owner_koid", object.peer_owner_koid, allocator);
process_objects_json.PushBack(object_json, allocator);
}
rapidjson::Value process_name(rapidjson::kObjectType);
const std::string s(process.name);
process_name.SetString(s.c_str(), static_cast<rapidjson::SizeType>(s.length()), allocator);
rapidjson::Value process_json(rapidjson::kObjectType);
process_json.AddMember("koid", process.koid, allocator)
.AddMember("name", process_name, allocator)
.AddMember("objects", process_objects_json, allocator);
processes_json.PushBack(process_json, allocator);
}
json_document.AddMember("Processes", processes_json, allocator);
rapidjson::StringBuffer buffer;
buffer.Clear();
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
json_document.Accept(writer);
return std::string(buffer.GetString(), buffer.GetSize());
}
zx_status_t GetHandles(zx::unowned_process process, std::vector<zx_info_handle_extended_t>* out) {
size_t avail = 8;
while (true) {
out->resize(avail);
auto size = avail * sizeof(zx_info_handle_extended_t);
size_t actual = 0;
if (auto status = process->get_info(ZX_INFO_HANDLE_TABLE, out->data(), size, &actual, &avail);
status != ZX_OK) {
return status;
}
if (actual < avail) {
avail *= 2u;
continue;
}
out->resize(actual);
return ZX_OK;
}
}
void FillPeerOwnerKoid(std::vector<Process>& processes_data) {
std::unordered_map<zx_koid_t, zx_koid_t> object_to_process;
for (const Process& process : processes_data) {
for (const KernelObject& object : process.objects) {
if (object.related_koid != 0) {
object_to_process[object.related_koid] = process.koid;
}
}
}
for (Process& process : processes_data) {
for (KernelObject& object : process.objects) {
if (object.related_koid != 0) {
if (object_to_process.find(object.koid) == object_to_process.end())
continue;
object.peer_owner_koid = object_to_process[object.koid];
}
}
}
}
} // namespace process_explorer