blob: 1e31d467a0ca62ff6c69ca73e044c7fa0830c68a [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.
// This simple program listens on the fuchsia::debugger::DebugAgent protocol,
// and launch a debug_agent when there's a connect request. The debug_agent
// launched expects a numbered handle at PA_HND(PA_USER0, 0), which should
// point to a zx::socket object.
#include <fuchsia/debugger/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fdio/spawn.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/syslog/cpp/log_settings.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/processargs.h>
namespace {
class DebugAgentLauncher : public fuchsia::debugger::DebugAgent {
public:
// Launch debug_agent on connect, passing the socket as a numbered handle.
void Connect(zx::socket socket, ConnectCallback callback) override {
FX_LOGS(DEBUG) << "Spawning debug_agent...";
const char* path = "/pkg/bin/debug_agent";
const char* argv[] = {path, "--channel-mode", nullptr};
fdio_spawn_action_t action = {
.action = FDIO_SPAWN_ACTION_ADD_HANDLE,
.h =
{
// Must correspond to main.cc.
.id = PA_HND(PA_USER0, 0),
.handle = socket.release(),
},
};
zx::process process;
char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH] = {};
zx_status_t status =
fdio_spawn_etc(zx_job_default(), FDIO_SPAWN_CLONE_ALL, path, argv,
/*environ=*/nullptr, 1, &action, process.reset_and_get_address(), err_msg);
if (status != ZX_OK) {
FX_PLOGS(ERROR, status) << "Failed to launch debug_agent: " << err_msg;
}
callback(status);
}
};
} // namespace
int main() {
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
syslog::SetLogSettings(syslog::LogSettings{});
DebugAgentLauncher launcher;
fidl::Binding<fuchsia::debugger::DebugAgent> binding(&launcher);
fidl::InterfaceRequestHandler<fuchsia::debugger::DebugAgent> handler =
[&](fidl::InterfaceRequest<fuchsia::debugger::DebugAgent> request) {
binding.Bind(std::move(request));
};
auto context = sys::ComponentContext::CreateAndServeOutgoingDirectory();
context->outgoing()->AddPublicService(std::move(handler));
FX_LOGS(INFO) << "Start listening on FIDL fuchsia::debugger::DebugAgent.";
return loop.Run();
}