blob: 2211f4f37ad3342c674b9c77ef74d592b4a97680 [file] [log] [blame]
// Copyright 2019 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/debug/zxdb/console/format_target.h"
#include <optional>
#include "src/developer/debug/ipc/records.h"
#include "src/developer/debug/zxdb/client/process.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/console/command_utils.h"
#include "src/developer/debug/zxdb/console/console_context.h"
#include "src/developer/debug/zxdb/console/format_table.h"
#include "src/developer/debug/zxdb/console/string_util.h"
#include "src/lib/fxl/strings/string_printf.h"
namespace zxdb {
namespace {
std::string GetComponentName(const std::optional<debug_ipc::ComponentInfo>& component_info) {
if (!component_info)
return "";
return component_info->url.substr(component_info->url.find_last_of('/') + 1);
}
} // namespace
OutputBuffer FormatTarget(ConsoleContext* context, const Target* target) {
OutputBuffer out("Process ");
out.Append(Syntax::kSpecial, std::to_string(context->IdForTarget(target)));
out.Append(Syntax::kVariable, " state");
out.Append("=" + FormatConsoleString(TargetStateToString(target->GetState())));
if (target->GetState() == Target::State::kRunning) {
const char* id_name = debug::PlatformProcessIdName(context->session()->platform(), false);
out.Append(" ");
out.Append(Syntax::kVariable, id_name);
out.Append("=" + std::to_string(target->GetProcess()->GetKoid()));
}
if (auto process = target->GetProcess()) {
out.Append(Syntax::kVariable, " name");
out.Append("=" + FormatConsoleString(process->GetName()));
if (process->GetComponentInfo().size() == 1) {
out.Append(Syntax::kVariable, " component");
out.Append("=" + FormatConsoleString(GetComponentName(process->GetComponentInfo()[0])));
} else if (!process->GetComponentInfo().empty()) {
out.Append(Syntax::kVariable, " components=");
auto& components = process->GetComponentInfo();
for (size_t i = 0; i < components.size(); i++) {
out.Append(FormatConsoleString(GetComponentName(components[i])));
if (i + 1 < components.size()) {
out.Append(",");
}
}
}
}
out.Append("\n");
return out;
}
OutputBuffer FormatTargetList(ConsoleContext* context, int indent) {
auto targets = context->session()->system().GetTargets();
int active_target_id = context->GetActiveTargetId();
bool show_components = context->session()->platform() == debug::Platform::kFuchsia;
// Sort by ID.
std::vector<std::pair<int, Target*>> id_targets;
for (auto& target : targets)
id_targets.push_back(std::make_pair(context->IdForTarget(target), target));
std::sort(id_targets.begin(), id_targets.end());
std::string indent_str(indent, ' ');
std::vector<std::vector<std::string>> rows;
for (const auto& [id, target] : id_targets) {
rows.emplace_back();
std::vector<std::string>& row = rows.back();
// "Current process" marker (or nothing).
if (id == active_target_id)
row.push_back(indent_str + GetCurrentRowMarker());
else
row.push_back(indent_str);
// ID.
row.push_back(std::to_string(id));
// State and koid (if running).
row.push_back(TargetStateToString(target->GetState()));
if (auto process = target->GetProcess()) {
row.push_back(std::to_string(process->GetKoid()));
row.push_back(process->GetName());
if (show_components && process->GetComponentInfo().size() == 1) {
row.push_back(GetComponentName(process->GetComponentInfo()[0]));
}
} else {
row.emplace_back();
}
}
const char* id_name = debug::PlatformProcessIdName(context->session()->platform(), true);
std::vector<ColSpec> cols{ColSpec(Align::kLeft),
ColSpec(Align::kRight, 0, "#", 0, Syntax::kSpecial),
ColSpec(Align::kLeft, 0, "State"), ColSpec(Align::kRight, 0, id_name),
ColSpec(Align::kLeft, 0, "Name")};
if (show_components) {
cols.push_back(ColSpec(Align::kLeft, 0, "Component"));
}
OutputBuffer out;
FormatTable(cols, rows, &out);
return out;
}
const char* TargetStateToString(Target::State state) {
switch (state) {
case Target::State::kNone:
return "Not running";
case Target::State::kStarting:
return "Starting";
case Target::State::kAttaching:
return "Attaching";
case Target::State::kRunning:
return "Running";
}
FX_NOTREACHED();
return "";
}
} // namespace zxdb