blob: 50b452f6136973718652605981adb6d0369fda3a [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 <iomanip>
#include <sstream>
#include "src/developer/debug/zxdb/client/remote_api.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/client/system.h"
#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/console/command.h"
#include "src/developer/debug/zxdb/console/console.h"
#include "src/developer/debug/zxdb/console/output_buffer.h"
#include "src/developer/debug/zxdb/console/verbs.h"
#include "src/lib/fxl/strings/string_printf.h"
namespace zxdb {
namespace {
// List Processes --------------------------------------------------------------
void OutputProcessTreeRecord(const debug_ipc::ProcessTreeRecord& rec,
int indent, OutputBuffer* output) {
std::ostringstream line;
line << std::setw(indent * 2) << "";
switch (rec.type) {
case debug_ipc::ProcessTreeRecord::Type::kJob:
line << 'j';
break;
case debug_ipc::ProcessTreeRecord::Type::kProcess:
line << 'p';
break;
default:
line << '?';
}
line << ": " << rec.koid << " " << rec.name << "\n";
output->Append(line.str());
for (const auto& child : rec.children)
OutputProcessTreeRecord(child, indent + 1, output);
}
void OnListProcessesComplete(const Err& err,
debug_ipc::ProcessTreeReply reply) {
OutputBuffer out;
if (err.has_error())
out.Append(err);
else
OutputProcessTreeRecord(reply.root, 0, &out);
Console::get()->Output(out);
}
const char kListProcessesShortHelp[] =
"ps: Prints the process tree of the debugged system.";
const char kListProcessesHelp[] =
R"(ps
Prints the process tree of the debugged system.)";
Err DoListProcesses(ConsoleContext* context, const Command& cmd) {
context->session()->system().GetProcessTree(&OnListProcessesComplete);
return Err();
}
// System Info -----------------------------------------------------------------
const char kSysInfoShortHelp[] =
"sys-info: Get general information about the target system.";
const char kSysInfoHelp[] =
R"(sys-info
Get general information about the target system.
This includes aspects such as build version, number of CPUs, memory, etc.)";
void OnSysInfo(const Err& err, debug_ipc::SysInfoReply sys_info) {
if (err.has_error()) {
Console::get()->Output(err);
return;
}
OutputBuffer out;
out.Append(fxl::StringPrintf("Version: %s\n", sys_info.version.c_str()));
out.Append(fxl::StringPrintf("Num CPUs: %u\n", sys_info.num_cpus));
// We don't have total ram for minidumps. We can assume a 0 value is always
// invalid and just not print it.
out.Append("Memory (MiB): ");
if (sys_info.memory_mb) {
out.Append(fxl::StringPrintf("%u\n", sys_info.memory_mb));
} else {
out.Append(Syntax::kComment, "<Unknown>\n");
}
out.Append(
fxl::StringPrintf("HW Breakpoints: %u\n", sys_info.hw_breakpoint_count));
out.Append(
fxl::StringPrintf("HW Watchpoints: %u\n", sys_info.hw_watchpoint_count));
Console::get()->Output(std::move(out));
}
Err DoSysInfo(ConsoleContext* context, const Command& cmd) {
debug_ipc::SysInfoRequest request;
context->session()->remote_api()->SysInfo(request, &OnSysInfo);
return Err();
}
} // namespace
void AppendSystemVerbs(std::map<Verb, VerbRecord>* verbs) {
(*verbs)[Verb::kListProcesses] =
VerbRecord(&DoListProcesses, {"ps"}, kListProcessesShortHelp,
kListProcessesHelp, CommandGroup::kGeneral);
(*verbs)[Verb::kSysInfo] =
VerbRecord(&DoSysInfo, {"sys-info"}, kSysInfoShortHelp, kSysInfoHelp,
CommandGroup::kGeneral);
}
} // namespace zxdb