Commit abed0c39 authored by Chris Letnick's avatar Chris Letnick Committed by Commit Bot

Add traced-process support to external_mojo processes.

To support tracing, a tracing service must also be registered with
the mojo broker.

This change does not implement start-up tracing which may be addressed
at a later time.

If (GN arg) enable_external_mojo_tracing=false (default), then a no-op
tracing client implementation will be used.

Bug: internal b/153566474
Test: Tested tracing with an external tracing service.
Change-Id: I56ccecde888778a3f9a54353bb3e6744fb8194c3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2200081Reviewed-by: default avatarAlex Sakhartchouk <alexst@chromium.org>
Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Reviewed-by: default avatarEric Seckler <eseckler@chromium.org>
Reviewed-by: default avatarKenneth MacKay <kmackay@chromium.org>
Commit-Queue: Chris Letnick <cletnick@google.com>
Cr-Commit-Position: refs/heads/master@{#770734}
parent 8beae8ee
...@@ -116,6 +116,10 @@ declare_args() { ...@@ -116,6 +116,10 @@ declare_args() {
# within cast_shell. # within cast_shell.
enable_external_mojo_services = is_linux enable_external_mojo_services = is_linux
# Support Perfetto tracing of processes that depend on entry points in
# //chromecast/external_mojo/external_service_support
enable_external_mojo_tracing = false
# Recording happens at this sample rate. Must be 16000, 48000 or 96000 Hz. # Recording happens at this sample rate. Must be 16000, 48000 or 96000 Hz.
audio_input_sample_rate = 16000 audio_input_sample_rate = 16000
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import("//chromecast/chromecast.gni")
source_set("external_service") { source_set("external_service") {
sources = [ sources = [
"external_connector.h", "external_connector.h",
...@@ -43,20 +45,72 @@ source_set("process_setup") { ...@@ -43,20 +45,72 @@ source_set("process_setup") {
} }
} }
source_set("tracing_client_hdr") {
sources = [
"tracing_client.h",
]
}
source_set("tracing_client_dummy") {
sources = [
"tracing_client_dummy.cc",
"tracing_client_dummy.h",
]
deps = [
":tracing_client_hdr",
]
}
source_set("tracing_client_impl") {
sources = [
"tracing_client_impl.cc",
"tracing_client_impl.h",
]
deps = [
":external_service",
":tracing_client_hdr",
"//base",
"//chromecast:chromecast_buildflags",
"//mojo/public/cpp/bindings",
"//services/tracing:lib",
"//services/tracing/public/cpp",
"//services/tracing/public/cpp:traced_process",
"//services/tracing/public/mojom",
]
}
group("tracing_client") {
public_deps = [
":tracing_client_hdr",
]
if (enable_external_mojo_tracing) {
public_deps += [ ":tracing_client_impl" ]
} else {
public_deps += [ ":tracing_client_dummy" ]
}
}
source_set("service_process") { source_set("service_process") {
sources = [ "service_process.h" ] sources = [
"service_process.h",
]
} }
source_set("standalone_service_main") { source_set("standalone_service_main") {
sources = [ "standalone_service_main.cc" ] sources = [
"standalone_service_main.cc",
]
deps = [ deps = [
":external_service", ":external_service",
":process_setup", ":process_setup",
":tracing_client",
"//base", "//base",
"//chromecast/external_mojo/public/cpp:common", "//chromecast/external_mojo/public/cpp:common",
"//mojo/core/embedder", "//mojo/core/embedder",
] ]
public_deps = [ ":service_process" ] public_deps = [
":service_process",
]
} }
source_set("chromium_service") { source_set("chromium_service") {
...@@ -75,9 +129,13 @@ source_set("chromium_service") { ...@@ -75,9 +129,13 @@ source_set("chromium_service") {
} }
executable("standalone_mojo_broker") { executable("standalone_mojo_broker") {
sources = [ "standalone_mojo_broker.cc" ] sources = [
"standalone_mojo_broker.cc",
]
deps = [ deps = [
":external_service",
":process_setup", ":process_setup",
":tracing_client",
"//base", "//base",
"//chromecast/external_mojo/public/cpp:common", "//chromecast/external_mojo/public/cpp:common",
"//chromecast/external_mojo/public/cpp:external_mojo_broker", "//chromecast/external_mojo/public/cpp:external_mojo_broker",
......
...@@ -2,4 +2,6 @@ include_rules = [ ...@@ -2,4 +2,6 @@ include_rules = [
"+chromecast/crash", "+chromecast/crash",
"+components/crash/core/app", "+components/crash/core/app",
"+mojo/core/embedder", "+mojo/core/embedder",
"+services/tracing",
"+third_party/perfetto/include/perfetto",
] ]
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -10,7 +11,10 @@ ...@@ -10,7 +11,10 @@
#include "base/message_loop/message_pump_type.h" #include "base/message_loop/message_pump_type.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/task/single_thread_task_executor.h" #include "base/task/single_thread_task_executor.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "chromecast/external_mojo/external_service_support/external_connector_impl.h"
#include "chromecast/external_mojo/external_service_support/process_setup.h" #include "chromecast/external_mojo/external_service_support/process_setup.h"
#include "chromecast/external_mojo/external_service_support/tracing_client.h"
#include "chromecast/external_mojo/public/cpp/common.h" #include "chromecast/external_mojo/public/cpp/common.h"
#include "chromecast/external_mojo/public/cpp/external_mojo_broker.h" #include "chromecast/external_mojo/public/cpp/external_mojo_broker.h"
#include "mojo/core/embedder/embedder.h" #include "mojo/core/embedder/embedder.h"
...@@ -33,10 +37,20 @@ int main(int argc, char** argv) { ...@@ -33,10 +37,20 @@ int main(int argc, char** argv) {
io_task_executor.task_runner(), io_task_executor.task_runner(),
mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN); mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);
base::ThreadPoolInstance::CreateAndStartWithDefaultParams(
"StandaloneMojoBroker");
chromecast::external_mojo::ExternalMojoBroker broker( chromecast::external_mojo::ExternalMojoBroker broker(
chromecast::external_mojo::GetBrokerPath()); chromecast::external_mojo::GetBrokerPath());
chromecast::external_service_support::ExternalConnectorImpl tracing_connector(
chromecast::external_mojo::GetBrokerPath(), broker.CreateConnector());
auto tracing_client =
chromecast::external_service_support::TracingClient::Create(
&tracing_connector);
run_loop.Run(); run_loop.Run();
base::ThreadPoolInstance::Get()->Shutdown();
return 0; return 0;
} }
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "chromecast/external_mojo/external_service_support/external_connector.h" #include "chromecast/external_mojo/external_service_support/external_connector.h"
#include "chromecast/external_mojo/external_service_support/process_setup.h" #include "chromecast/external_mojo/external_service_support/process_setup.h"
#include "chromecast/external_mojo/external_service_support/service_process.h" #include "chromecast/external_mojo/external_service_support/service_process.h"
#include "chromecast/external_mojo/external_service_support/tracing_client.h"
#include "chromecast/external_mojo/public/cpp/common.h" #include "chromecast/external_mojo/public/cpp/common.h"
#include "mojo/core/embedder/embedder.h" #include "mojo/core/embedder/embedder.h"
#include "mojo/core/embedder/scoped_ipc_support.h" #include "mojo/core/embedder/scoped_ipc_support.h"
...@@ -26,6 +27,8 @@ struct GlobalState { ...@@ -26,6 +27,8 @@ struct GlobalState {
service_process; service_process;
std::unique_ptr<chromecast::external_service_support::ExternalConnector> std::unique_ptr<chromecast::external_service_support::ExternalConnector>
connector; connector;
std::unique_ptr<chromecast::external_service_support::TracingClient>
tracing_client;
}; };
void OnConnected( void OnConnected(
...@@ -33,6 +36,9 @@ void OnConnected( ...@@ -33,6 +36,9 @@ void OnConnected(
std::unique_ptr<chromecast::external_service_support::ExternalConnector> std::unique_ptr<chromecast::external_service_support::ExternalConnector>
connector) { connector) {
state->connector = std::move(connector); state->connector = std::move(connector);
state->tracing_client =
chromecast::external_service_support::TracingClient::Create(
state->connector.get());
state->service_process = state->service_process =
chromecast::external_service_support::ServiceProcess::Create( chromecast::external_service_support::ServiceProcess::Create(
state->connector.get()); state->connector.get());
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_EXTERNAL_MOJO_EXTERNAL_SERVICE_SUPPORT_TRACING_CLIENT_H_
#define CHROMECAST_EXTERNAL_MOJO_EXTERNAL_SERVICE_SUPPORT_TRACING_CLIENT_H_
#include <memory>
#include <string>
namespace chromecast {
namespace external_service_support {
class ExternalConnector;
// TracingClient Supports the tracing of processes that connect to a central
// tracing service through an ExternalConnector.
class TracingClient {
public:
TracingClient() = default;
virtual ~TracingClient() = default;
static const char kTracingServiceName[];
static std::unique_ptr<TracingClient> Create(ExternalConnector* connector);
private:
TracingClient(const TracingClient&) = delete;
TracingClient& operator=(const TracingClient&) = delete;
};
} // namespace external_service_support
} // namespace chromecast
#endif // CHROMECAST_EXTERNAL_MOJO_EXTERNAL_SERVICE_SUPPORT_TRACING_CLIENT_H_
// Copyright 2020 The Chromium 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 "chromecast/external_mojo/external_service_support/tracing_client_dummy.h"
namespace chromecast {
namespace external_service_support {
// static
const char TracingClient::kTracingServiceName[] = "unknown";
// static
std::unique_ptr<TracingClient> TracingClient::Create(
ExternalConnector* connector) {
return std::make_unique<TracingClientDummy>();
}
} // namespace external_service_support
} // namespace chromecast
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_EXTERNAL_MOJO_EXTERNAL_SERVICE_SUPPORT_TRACING_CLIENT_DUMMY_H_
#define CHROMECAST_EXTERNAL_MOJO_EXTERNAL_SERVICE_SUPPORT_TRACING_CLIENT_DUMMY_H_
#include "chromecast/external_mojo/external_service_support/tracing_client.h"
namespace chromecast {
namespace external_service_support {
// Dummy implementation for build configurations that do not enable tracing.
class TracingClientDummy : public TracingClient {
public:
TracingClientDummy() = default;
~TracingClientDummy() override = default;
private:
TracingClientDummy(const TracingClientDummy&) = delete;
TracingClientDummy& operator=(const TracingClientDummy&) = delete;
};
} // namespace external_service_support
} // namespace chromecast
#endif // CHROMECAST_EXTERNAL_MOJO_EXTERNAL_SERVICE_SUPPORT_TRACING_CLIENT_DUMMY_H_
// Copyright 2020 The Chromium 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 "chromecast/external_mojo/external_service_support/tracing_client_impl.h"
#include "base/command_line.h"
#include "base/process/process.h"
#include "base/trace_event/trace_event.h"
#include "chromecast/external_mojo/external_service_support/external_connector.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "services/tracing/public/cpp/trace_startup.h"
#include "services/tracing/public/cpp/traced_process.h"
#include "services/tracing/public/mojom/traced_process.mojom.h"
namespace chromecast {
namespace external_service_support {
// static
const char TracingClient::kTracingServiceName[] = "external_tracing";
// static
std::unique_ptr<TracingClient> TracingClient::Create(
ExternalConnector* connector) {
return std::make_unique<TracingClientImpl>(connector);
}
TracingClientImpl::TracingClientImpl(ExternalConnector* connector)
: connector_(connector) {
DCHECK(connector_);
// Setup this process.
base::trace_event::TraceLog::GetInstance()->set_process_name(
base::CommandLine::ForCurrentProcess()->GetProgram().value());
// TODO(cletnick): Support initializing startup tracing without
// depending on per-process command-line arguments.
tracing::EnableStartupTracingIfNeeded();
tracing::InitTracingPostThreadPoolStartAndFeatureList();
// Connect to service.
connector_->BindInterface(TracingClient::kTracingServiceName,
tracing_service_.BindNewPipeAndPassReceiver());
// base::Unretained(this) is safe here because the mojo::Remote
// |tracing_service_| is owned by |this| and will not run the registered
// callback after destruction.
tracing_service_.set_disconnect_handler(base::BindOnce(
&TracingClientImpl::TracingServiceDisconnected, base::Unretained(this)));
// Register with service.
mojo::PendingRemote<tracing::mojom::TracedProcess> remote_process;
tracing::TracedProcess::OnTracedProcessRequest(
remote_process.InitWithNewPipeAndPassReceiver());
tracing_service_->AddClient(tracing::mojom::ClientInfo::New(
base::Process::Current().Pid(), std::move(remote_process)));
}
TracingClientImpl::~TracingClientImpl() = default;
void TracingClientImpl::TracingServiceDisconnected() {
tracing_service_.reset();
tracing::TracedProcess::ResetTracedProcessReceiver();
LOG(ERROR) << "Disconnected from tracing service. Not reconnecting.";
}
} // namespace external_service_support
} // namespace chromecast
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_EXTERNAL_MOJO_EXTERNAL_SERVICE_SUPPORT_TRACING_CLIENT_IMPL_H_
#define CHROMECAST_EXTERNAL_MOJO_EXTERNAL_SERVICE_SUPPORT_TRACING_CLIENT_IMPL_H_
#include "chromecast/external_mojo/external_service_support/tracing_client.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/tracing/public/mojom/tracing_service.mojom.h"
namespace chromecast {
namespace external_service_support {
class ExternalConnector;
// TracingClient implementation for connecting to a tracing::TracingService
// instance through an external mojo broker.
class TracingClientImpl : public TracingClient {
public:
explicit TracingClientImpl(ExternalConnector* connector);
~TracingClientImpl() override;
private:
void TracingServiceDisconnected();
mojo::Remote<tracing::mojom::TracingService> tracing_service_;
ExternalConnector* const connector_;
TracingClientImpl(const TracingClientImpl&) = delete;
TracingClientImpl& operator=(const TracingClientImpl&) = delete;
};
} // namespace external_service_support
} // namespace chromecast
#endif // CHROMECAST_EXTERNAL_MOJO_EXTERNAL_SERVICE_SUPPORT_TRACING_CLIENT_IMPL_H_
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "base/message_loop/message_pump_for_io.h" #include "base/message_loop/message_pump_for_io.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/token.h" #include "base/token.h"
#include "base/trace_event/trace_event.h"
#include "chromecast/external_mojo/public/cpp/common.h" #include "chromecast/external_mojo/public/cpp/common.h"
#include "chromecast/external_mojo/public/mojom/connector.mojom.h" #include "chromecast/external_mojo/public/mojom/connector.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
...@@ -223,6 +224,8 @@ class ExternalMojoBroker::ConnectorImpl : public mojom::ExternalConnector { ...@@ -223,6 +224,8 @@ class ExternalMojoBroker::ConnectorImpl : public mojom::ExternalConnector {
LOG(ERROR) << "Duplicate service " << service_name; LOG(ERROR) << "Duplicate service " << service_name;
return; return;
} }
TRACE_EVENT_INSTANT1("mojom", "RegisterService", TRACE_EVENT_SCOPE_THREAD,
"service", service_name);
LOG(INFO) << "Register service " << service_name; LOG(INFO) << "Register service " << service_name;
mojo::Remote<mojom::ExternalService> service(std::move(service_remote)); mojo::Remote<mojom::ExternalService> service(std::move(service_remote));
service.set_disconnect_handler(base::BindOnce( service.set_disconnect_handler(base::BindOnce(
...@@ -248,6 +251,8 @@ class ExternalMojoBroker::ConnectorImpl : public mojom::ExternalConnector { ...@@ -248,6 +251,8 @@ class ExternalMojoBroker::ConnectorImpl : public mojom::ExternalConnector {
const std::string& interface_name, const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override { mojo::ScopedMessagePipeHandle interface_pipe) override {
LOG(INFO) << "Request for " << service_name << ":" << interface_name; LOG(INFO) << "Request for " << service_name << ":" << interface_name;
TRACE_EVENT_INSTANT1("mojom", "BindToService", TRACE_EVENT_SCOPE_THREAD,
"service", service_name);
auto it = services_.find(service_name); auto it = services_.find(service_name);
if (it != services_.end()) { if (it != services_.end()) {
LOG(INFO) << "Found externally-registered " << service_name; LOG(INFO) << "Found externally-registered " << service_name;
...@@ -322,6 +327,8 @@ class ExternalMojoBroker::ConnectorImpl : public mojom::ExternalConnector { ...@@ -322,6 +327,8 @@ class ExternalMojoBroker::ConnectorImpl : public mojom::ExternalConnector {
void OnServiceLost(const std::string& service_name) { void OnServiceLost(const std::string& service_name) {
LOG(INFO) << service_name << " disconnected"; LOG(INFO) << service_name << " disconnected";
TRACE_EVENT_INSTANT1("mojom", "ServiceDisconnected",
TRACE_EVENT_SCOPE_THREAD, "service", service_name);
services_.erase(service_name); services_.erase(service_name);
services_info_[service_name].disconnect_time = base::TimeTicks::Now(); services_info_[service_name].disconnect_time = base::TimeTicks::Now();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment