blob: 425cd55bc63bc30e3b0c0da905677d3ed0f5d012 [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 "src/developer/debug/zxdb/client/process.h"
#include "src/developer/debug/zxdb/client/session.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 {
// Returns the process name of the given target, depending on the running
// process or the current app name, as applicable.
std::string GetTargetName(const Target* target) {
// When running, use the object name if any.
std::string name;
if (target->GetState() == Target::State::kRunning)
name = target->GetProcess()->GetName();
// Otherwise fall back to the program name which is the first arg.
if (name.empty()) {
const std::vector<std::string>& args = target->GetArgs();
if (!args.empty())
name += args[0];
}
return name;
}
} // namespace
OutputBuffer FormatTarget(ConsoleContext* context, const Target* target) {
int id = context->IdForTarget(target);
const char* state = TargetStateToString(target->GetState());
// Koid string. This includes a trailing space when present so it can be
// concat'd even when not present and things look nice.
std::string koid_str;
if (target->GetState() == Target::State::kRunning) {
koid_str = fxl::StringPrintf("koid=%" PRIu64 " ", target->GetProcess()->GetKoid());
}
std::string result = fxl::StringPrintf("Process %d [%s] %s", id, state, koid_str.c_str());
result += GetTargetName(target);
return result;
}
OutputBuffer FormatTargetList(ConsoleContext* context, int indent) {
auto targets = context->session()->system().GetTargets();
int active_target_id = context->GetActiveTargetId();
// 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& pair : id_targets) {
rows.emplace_back();
std::vector<std::string>& row = rows.back();
// "Current process" marker (or nothing).
if (pair.first == active_target_id)
row.push_back(indent_str + GetRightArrow());
else
row.push_back(indent_str);
// ID.
row.push_back(fxl::StringPrintf("%d", pair.first));
// State and koid (if running).
row.push_back(TargetStateToString(pair.second->GetState()));
if (pair.second->GetState() == Target::State::kRunning) {
row.push_back(fxl::StringPrintf("%" PRIu64, pair.second->GetProcess()->GetKoid()));
} else {
row.emplace_back();
}
row.push_back(GetTargetName(pair.second));
}
OutputBuffer out;
FormatTable({ColSpec(Align::kLeft), ColSpec(Align::kRight, 0, "#", 0, Syntax::kSpecial),
ColSpec(Align::kLeft, 0, "State"), ColSpec(Align::kRight, 0, "Koid"),
ColSpec(Align::kLeft, 0, "Name")},
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";
}
FXL_NOTREACHED();
return "";
}
} // namespace zxdb