diff --git a/base/cvd/build_external/build_external.MODULE.bazel b/base/cvd/build_external/build_external.MODULE.bazel index b657326b2fb..f273bb28efb 100644 --- a/base/cvd/build_external/build_external.MODULE.bazel +++ b/base/cvd/build_external/build_external.MODULE.bazel @@ -48,6 +48,7 @@ include("//build_external/mkbootimg:mkbootimg.MODULE.bazel") include("//build_external/ms-tpm-20-ref:ms-tpm-20-ref.MODULE.bazel") include("//build_external/mtools:mtools.MODULE.bazel") include("//build_external/opengl_headers:opengl_headers.MODULE.bazel") +include("//build_external/perfetto:perfetto.MODULE.bazel") include("//build_external/pyyaml:pyyaml.MODULE.bazel") include("//build_external/re2:re2.MODULE.bazel") include("//build_external/rootcanal:rootcanal.MODULE.bazel") diff --git a/base/cvd/build_external/perfetto/BUILD b/base/cvd/build_external/perfetto/BUILD new file mode 100644 index 00000000000..e69de29bb2d diff --git a/base/cvd/build_external/perfetto/perfetto.MODULE.bazel b/base/cvd/build_external/perfetto/perfetto.MODULE.bazel new file mode 100644 index 00000000000..b0b07b7ab36 --- /dev/null +++ b/base/cvd/build_external/perfetto/perfetto.MODULE.bazel @@ -0,0 +1,3 @@ +perfetto_ext = use_extension("//build_external/perfetto:repositories.bzl", "perfetto_extension") +use_repo(perfetto_ext, "perfetto") +use_repo(perfetto_ext, "perfetto_cfg") diff --git a/base/cvd/build_external/perfetto/repositories.bzl b/base/cvd/build_external/perfetto/repositories.bzl new file mode 100644 index 00000000000..1d4a95ccb04 --- /dev/null +++ b/base/cvd/build_external/perfetto/repositories.bzl @@ -0,0 +1,35 @@ +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +# https://github.com/google/perfetto/issues/2787 for Perfetto getting into the +# Central Repository. +def _perfetto_extension_impl(_): + URL = "https://github.com/google/perfetto/archive/refs/tags/v54.0.tar.gz" + http_archive( + name = "perfetto", + url = URL, + strip_prefix = "perfetto-54.0", + patch_cmds = [ + # Hack away all of the Android specific dependencies: + "sed -i '/load(\"@rules_android/d' bazel/rules.bzl", + "sed -i '/load(\"@perfetto\\/\\/bazel:run_ait_with_adb.bzl/d' bazel/rules.bzl", + "sed -i 's| android_binary(\\*\\*kwargs)| return|g' bazel/rules.bzl", + "sed -i 's| android_library(\\*\\*kwargs)| return|g' bazel/rules.bzl", + "sed -i 's| android_instrumentation_test(\\*\\*kwargs)| return|g' bazel/rules.bzl", + ], + ) + + # perfetto_cfg is a new_local_repository using a path relative to the top-level WORKSPACE file. + # We replicate this with an http_archive using a bigger strip_prefix. + http_archive( + name = "perfetto_cfg", + url = URL, + strip_prefix = "perfetto-54.0/bazel/standalone", + build_file_content = "# empty BUILD to make a bazel package", + patch_cmds = [ + "sed -i 's|@com_google_protobuf|@protobuf|g' perfetto_cfg.bzl", + ], + ) + +perfetto_extension = module_extension( + implementation = _perfetto_extension_impl, +) diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/BUILD.bazel b/base/cvd/cuttlefish/host/commands/assemble_cvd/BUILD.bazel index 7389abac3fa..f5471d1a1af 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/BUILD.bazel @@ -71,6 +71,7 @@ cf_cc_binary( "//cuttlefish/host/libs/config/defaults", "//cuttlefish/host/libs/config/fastboot", "//cuttlefish/host/libs/feature:inject", + "//cuttlefish/host/libs/tracing:tracing", "//cuttlefish/posix:symlink", "//cuttlefish/pretty:vector", "//libbase", @@ -166,6 +167,7 @@ cf_cc_library( "//cuttlefish/common/libs/utils:subprocess", "//cuttlefish/common/libs/utils:subprocess_managed_stdio", "//cuttlefish/host/libs/config:config_utils", + "//cuttlefish/host/libs/tracing", "//cuttlefish/posix:strerror", "//cuttlefish/result", "//libbase", @@ -220,6 +222,7 @@ cf_cc_library( "//cuttlefish/host/libs/config:file_source", "//cuttlefish/host/libs/config:instance_nums", "//cuttlefish/host/libs/feature:inject", + "//cuttlefish/host/libs/tracing:tracing", "//cuttlefish/result", "//libbase", "@abseil-cpp//absl/log", @@ -237,6 +240,7 @@ cf_cc_library( "//cuttlefish/host/libs/config:vmm_mode", "//cuttlefish/host/libs/image_aggregator", "//cuttlefish/host/libs/image_aggregator:qcow2", + "//cuttlefish/host/libs/tracing", "//cuttlefish/result", "//libbase", "@abseil-cpp//absl/log", @@ -354,6 +358,7 @@ cf_cc_library( "//cuttlefish/host/libs/config:secure_hals", "//cuttlefish/host/libs/config:vmm_mode", "//cuttlefish/host/libs/config/defaults", + "//cuttlefish/host/libs/tracing", "//cuttlefish/host/libs/vhal_proxy_server", "//cuttlefish/host/libs/vm_manager", "//cuttlefish/result", @@ -402,6 +407,7 @@ cf_cc_library( "//cuttlefish/host/libs/config:config_utils", "//cuttlefish/host/libs/config:display", "//cuttlefish/host/libs/config:gpu_mode", + "//cuttlefish/host/libs/tracing", "//cuttlefish/pretty", "//cuttlefish/pretty:optional", "//cuttlefish/pretty:string", @@ -431,6 +437,7 @@ cf_cc_library( "//cuttlefish/host/libs/config:guest_hwui_renderer", "//cuttlefish/host/libs/config:guest_renderer_preload", "//cuttlefish/host/libs/config:vmm_mode", + "//cuttlefish/host/libs/tracing", "//cuttlefish/result", "//libbase", "@abseil-cpp//absl/log", diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/assemble_cvd.cc b/base/cvd/cuttlefish/host/commands/assemble_cvd/assemble_cvd.cc index 6324fab8806..3b7a649ea3a 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/assemble_cvd.cc +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/assemble_cvd.cc @@ -69,6 +69,7 @@ #include "cuttlefish/host/libs/config/fetcher_configs.h" #include "cuttlefish/host/libs/config/log_string_to_dir.h" #include "cuttlefish/host/libs/feature/inject.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/posix/symlink.h" #include "cuttlefish/pretty/vector.h" @@ -405,6 +406,8 @@ Result InitFilesystemAndCreateConfig( CF_EXPECT(CleanPriorFiles(preserving, clean_dirs), "Failed to clean prior files"); + CF_TRACE_EVENT("SetupDirectories"); + std::string default_group = "cvdnetwork"; const mode_t default_mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; @@ -573,6 +576,9 @@ Result AssembleCvdMain(int argc, char** argv) { CF_EXPECT(CheckNoTTY()); + auto scoped_trace_flusher = InitializeTracing(); + CF_TRACE_EVENT("AssembleCvd"); + // Read everything that cvd_internal_start writes, but ignore it since // fetcher_config.json will be searched for in the system image directory. (void) CF_EXPECT(ReadInputFiles()); @@ -643,10 +649,12 @@ Result AssembleCvdMain(int argc, char** argv) { "Failed to parse flags."); if (help || !help_str.empty()) { + CF_TRACE_EVENT_INSTANT("Help"); LOG(WARNING) << "TODO(schuffelen): Implement `--help` for assemble_cvd."; LOG(WARNING) << "In the meantime, call `launch_cvd --help`"; return 1; } else if (helpxml) { + CF_TRACE_EVENT_INSTANT("Help"); if (!FlagFeature::WriteGflagsHelpXml(flag_features, std::cout)) { LOG(ERROR) << "Failure in writing gflags helpxml output"; } diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/clean.cc b/base/cvd/cuttlefish/host/commands/assemble_cvd/clean.cc index f3b8e971579..f77f763d30f 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/clean.cc +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/clean.cc @@ -31,6 +31,7 @@ #include "cuttlefish/common/libs/utils/subprocess.h" #include "cuttlefish/common/libs/utils/subprocess_managed_stdio.h" #include "cuttlefish/host/libs/config/config_utils.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/posix/strerror.h" #include "cuttlefish/result/result.h" @@ -137,6 +138,8 @@ Result CleanPriorFiles(const std::vector& paths, Result CleanPriorFiles(const std::set& preserving, const std::vector& clean_dirs) { + CF_TRACE_EVENT("CleanPriorFiles"); + std::vector paths = { // The global link to the config file GetGlobalConfigFileLink(), diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/create_dynamic_disk_files.cc b/base/cvd/cuttlefish/host/commands/assemble_cvd/create_dynamic_disk_files.cc index fa25fe0aa25..b3bb401799d 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/create_dynamic_disk_files.cc +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/create_dynamic_disk_files.cc @@ -59,6 +59,7 @@ #include "cuttlefish/host/libs/config/fetcher_config.h" #include "cuttlefish/host/libs/config/fetcher_configs.h" #include "cuttlefish/host/libs/config/file_source.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/result/result.h" namespace cuttlefish { @@ -98,6 +99,7 @@ Result CreateDynamicDiskFiles( const FetcherConfigs& fetcher_configs, const CuttlefishConfig& config, AndroidBuilds& android_builds, const BootImageFlag& boot_image, const SystemImageDirFlag& system_image_dirs) { + CF_TRACE_EVENT("CreateDynamicDiskFiles"); std::vector>> image_files = InstanceImageFiles(config, boot_image); size_t instance_index = 0; diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/disk_builder.cpp b/base/cvd/cuttlefish/host/commands/assemble_cvd/disk_builder.cpp index 6fdb6390210..c750653936e 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/disk_builder.cpp +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/disk_builder.cpp @@ -26,6 +26,7 @@ #include "cuttlefish/host/libs/config/vmm_mode.h" #include "cuttlefish/host/libs/image_aggregator/image_aggregator.h" #include "cuttlefish/host/libs/image_aggregator/qcow2.h" +#include "cuttlefish/host/libs/tracing/tracing.h" namespace cuttlefish { @@ -199,6 +200,8 @@ Result DiskBuilder::WillRebuildCompositeDisk() { } Result DiskBuilder::BuildCompositeDiskIfNecessary() { + CF_TRACE_EVENT("BuildCompositeDisk", "disk", composite_disk_path_); + if (!entire_disk_.empty()) { VLOG(0) << "No composite disk to build"; return false; @@ -228,6 +231,9 @@ Result DiskBuilder::BuildCompositeDiskIfNecessary() { } Result DiskBuilder::BuildOverlayIfNecessary() { + CF_TRACE_EVENT("BuildOverlayIfNcessary", + "overlay", overlay_path_); + #ifdef __APPLE__ return false; #else diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/flags.cc b/base/cvd/cuttlefish/host/commands/assemble_cvd/flags.cc index 507ada1063a..a91eaf98fe9 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/flags.cc +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/flags.cc @@ -90,6 +90,7 @@ #include "cuttlefish/host/libs/config/instance_nums.h" #include "cuttlefish/host/libs/config/secure_hals.h" #include "cuttlefish/host/libs/config/vmm_mode.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/host/libs/vhal_proxy_server/vhal_proxy_server_eth_addr.h" #include "cuttlefish/host/libs/vm_manager/gem5_manager.h" #include "cuttlefish/host/libs/vm_manager/qemu_manager.h" @@ -352,6 +353,8 @@ Result InitializeCuttlefishConfiguration( const SystemImageDirFlag& system_image_dir, const VendorBootImageFlag& vendor_boot_image, const VmManagerFlag& vm_manager_flag, const Defaults& defaults) { + CF_TRACE_EVENT("InitializeCuttlefishConfiguration"); + CuttlefishConfig tmp_config_obj; // If a snapshot path is provided, do not read all flags to set up the config. // Instead, read the config that was saved at time of snapshot and restore diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/graphics_flags.cc b/base/cvd/cuttlefish/host/commands/assemble_cvd/graphics_flags.cc index 31bed995094..9d35cb34421 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/graphics_flags.cc +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/graphics_flags.cc @@ -39,6 +39,7 @@ #include "cuttlefish/host/libs/config/guest_hwui_renderer.h" #include "cuttlefish/host/libs/config/guest_renderer_preload.h" #include "cuttlefish/host/libs/config/vmm_mode.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #ifdef __APPLE__ #define CF_UNUSED_ON_MACOS [[maybe_unused]] @@ -681,6 +682,8 @@ static std::unordered_set kSupportedGpuContexts{ gfxstream::proto::GraphicsAvailability GetGraphicsAvailabilityWithSubprocessCheck() { + CF_TRACE_EVENT("GetGraphicsAvailability"); + #ifdef __APPLE__ return {}; #else @@ -734,6 +737,8 @@ Result ConfigureGpuSettings( const std::string& guest_renderer_preload_arg, VmmMode vmm, const GuestConfig& guest_config, CuttlefishConfig::MutableInstanceSpecific& instance) { + CF_TRACE_EVENT_FUNC(); + #ifdef __APPLE__ (void)graphics_availability; (void)gpu_vhost_user_mode_arg; diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/guest_config.cc b/base/cvd/cuttlefish/host/commands/assemble_cvd/guest_config.cc index 808d709ec34..e6690df0c4a 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/guest_config.cc +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/guest_config.cc @@ -46,6 +46,7 @@ #include "cuttlefish/host/libs/config/config_utils.h" #include "cuttlefish/host/libs/config/display.h" #include "cuttlefish/host/libs/config/gpu_mode.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/pretty/optional.h" #include "cuttlefish/pretty/string.h" @@ -309,6 +310,8 @@ PrettyStruct Pretty(const GuestConfig& config, PrettyAdlPlaceholder) { Result> ReadGuestConfig( const BootImageFlag& boot_image, const KernelPathFlag& kernel_path, const SystemImageDirFlag& system_image_dirs) { + CF_TRACE_EVENT("ReadGuestConfig"); + std::vector guest_configs; const std::string env_path = fmt::format( diff --git a/base/cvd/cuttlefish/host/commands/cvd/BUILD.bazel b/base/cvd/cuttlefish/host/commands/cvd/BUILD.bazel index 94c919dc180..909865bfb74 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/cvd/BUILD.bazel @@ -37,6 +37,7 @@ cf_cc_binary( "//cuttlefish/common/libs/utils:tee_logging", "//cuttlefish/host/commands/cvd/utils", "//cuttlefish/host/commands/cvd/version", + "//cuttlefish/host/libs/tracing:tracing", "//cuttlefish/host/libs/vm_manager", "//cuttlefish/posix:strerror", "//libbase", diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/BUILD.bazel b/base/cvd/cuttlefish/host/commands/cvd/cli/BUILD.bazel index 70e88396071..34afe532e1c 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/BUILD.bazel @@ -109,6 +109,7 @@ cf_cc_library( "//cuttlefish/host/commands/cvd/instances:instance_manager", "//cuttlefish/host/commands/cvd/instances/lock", "//cuttlefish/host/commands/cvd/utils", + "//cuttlefish/host/libs/tracing", "//cuttlefish/host/libs/metrics:device_metrics_orchestration", "//cuttlefish/posix:strerror", "//cuttlefish/posix:symlink", diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/BUILD.bazel b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/BUILD.bazel index 83389e9dc67..500be162eb4 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/BUILD.bazel @@ -146,6 +146,7 @@ cf_cc_library( "//cuttlefish/host/commands/cvd/fetch:fetch_cvd_parser", "//cuttlefish/host/commands/cvd/utils", "//cuttlefish/host/commands/cvd/utils:common", + "//cuttlefish/host/libs/tracing", "//cuttlefish/host/libs/metrics:fetch_metrics_orchestration", "//cuttlefish/result", "//libbase", @@ -381,6 +382,7 @@ cf_cc_library( "//cuttlefish/host/libs/config:config_constants", "//cuttlefish/host/libs/config:cuttlefish_config", "//cuttlefish/host/libs/metrics:device_metrics_orchestration", + "//cuttlefish/host/libs/tracing", "//cuttlefish/posix:symlink", "//cuttlefish/result", "//libbase", diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/create.cpp b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/create.cpp index 4bd72ed37af..0005efd0c24 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/create.cpp +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/create.cpp @@ -50,6 +50,7 @@ #include "cuttlefish/host/commands/cvd/instances/instance_manager.h" #include "cuttlefish/host/commands/cvd/instances/local_instance_group.h" #include "cuttlefish/host/commands/cvd/utils/common.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/posix/strerror.h" #include "cuttlefish/posix/symlink.h" #include "cuttlefish/result/result.h" @@ -294,6 +295,8 @@ Result CvdCreateCommandHandler::CreateSymlinks( } Result CvdCreateCommandHandler::Handle(const CommandRequest& request) { + CF_TRACE_EVENT("cvd create"); + CF_EXPECT(CanHandle(request)); std::vector subcmd_args = request.SubcommandArguments(); @@ -304,7 +307,11 @@ Result CvdCreateCommandHandler::Handle(const CommandRequest& request) { if (!flags.config_file.empty()) { auto subrequest = CF_EXPECT(CreateLoadCommand(request, subcmd_args, flags.config_file)); - CF_EXPECT(command_executor_.ExecuteOne(subrequest, std::cerr)); + + { + CF_TRACE_EVENT("cvd load"); + CF_EXPECT(command_executor_.ExecuteOne(subrequest, std::cerr)); + } return {}; } @@ -329,7 +336,11 @@ Result CvdCreateCommandHandler::Handle(const CommandRequest& request) { if (flags.start) { auto start_cmd = CF_EXPECT(CreateStartCommand(group, subcmd_args, envs)); - CF_EXPECT(command_executor_.ExecuteOne(start_cmd, std::cerr)); + + { + CF_TRACE_EVENT("cvd start"); + CF_EXPECT(command_executor_.ExecuteOne(start_cmd, std::cerr)); + } if (CF_EXPECT(IsDefaultGroup(request))) { // For backward compatibility, we add extra symlink in system wide home diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/fetch.cpp b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/fetch.cpp index 9d726e58e8d..3e731d181e2 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/fetch.cpp +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/fetch.cpp @@ -35,6 +35,7 @@ #include "cuttlefish/host/commands/cvd/fetch/fetch_cvd_parser.h" #include "cuttlefish/host/commands/cvd/utils/common.h" #include "cuttlefish/host/libs/metrics/fetch_metrics_orchestration.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/result/result.h" namespace cuttlefish { @@ -51,6 +52,8 @@ class CvdFetchCommandHandler : public CvdCommandHandler { }; Result CvdFetchCommandHandler::Handle(const CommandRequest& request) { + CF_TRACE_EVENT_FUNC(); + CF_EXPECT(CanHandle(request)); std::vector args = request.SubcommandArguments(); diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.cpp b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.cpp index 2c039323ce3..0581b56dba0 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.cpp +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.cpp @@ -68,6 +68,7 @@ #include "cuttlefish/host/libs/config/config_constants.h" #include "cuttlefish/host/libs/config/cuttlefish_config.h" #include "cuttlefish/host/libs/metrics/device_metrics_orchestration.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/posix/symlink.h" #include "cuttlefish/result/result.h" @@ -457,6 +458,7 @@ Result CvdStartCommandHandler::Handle(const CommandRequest& request) { } static Result CvdResetGroup(const LocalInstanceGroup& group) { + CF_TRACE_EVENT("CvdResetGroup"); // We can't run stop_cvd here. It may hang forever, and doesn't make sense // to interrupt it. const auto& instances = group.Instances(); @@ -469,6 +471,7 @@ static Result CvdResetGroup(const LocalInstanceGroup& group) { Result CvdStartCommandHandler::LaunchDevice( Command launch_command, LocalInstanceGroup& group, const cvd_common::Envs& envs, const CommandRequest& request) { + CF_TRACE_EVENT("LaunchDevice"); // Don't destroy the returned object until after the devices have started, it // holds a connection to the orchestrator that ensures the devices remain // pre-registered there. If the connection is lost before the devices register @@ -509,6 +512,7 @@ Result CvdStartCommandHandler::LaunchDevice( Result CvdStartCommandHandler::LaunchDeviceInterruptible( Command command, LocalInstanceGroup& group, const cvd_common::Envs& envs, const CommandRequest& request) { + CF_TRACE_EVENT("LaunchDeviceInterruptible"); // cvd_internal_start uses the config from the previous invocation to // determine the default value for the -report_anonymous_usage_stats flag so // we symlink that to the group's home directory, this link will be @@ -531,6 +535,7 @@ Result CvdStartCommandHandler::LaunchDeviceInterruptible( Result CvdStartCommandHandler::DetailedHelp( const CommandRequest& request) const { + CF_TRACE_EVENT("cvd start help"); cvd_common::Envs envs = request.Env(); Result group_res = selector::SelectGroup(instance_manager_, request); diff --git a/base/cvd/cuttlefish/host/commands/cvd/fetch/BUILD.bazel b/base/cvd/cuttlefish/host/commands/cvd/fetch/BUILD.bazel index 7cc4528febb..207072df4fa 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/fetch/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/cvd/fetch/BUILD.bazel @@ -198,6 +198,7 @@ cf_cc_library( "//cuttlefish/host/libs/config:fetcher_config", "//cuttlefish/host/libs/config:file_source", "//cuttlefish/host/libs/image_aggregator:sparse_image", + "//cuttlefish/host/libs/tracing", "//cuttlefish/host/libs/web:android_build", "//cuttlefish/host/libs/web:android_build_string", "//cuttlefish/host/libs/web:chrome_os_build_string", diff --git a/base/cvd/cuttlefish/host/commands/cvd/fetch/fetch_cvd.cc b/base/cvd/cuttlefish/host/commands/cvd/fetch/fetch_cvd.cc index 41ae936f53e..0177be18119 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/fetch/fetch_cvd.cc +++ b/base/cvd/cuttlefish/host/commands/cvd/fetch/fetch_cvd.cc @@ -48,6 +48,7 @@ #include "cuttlefish/host/libs/config/fetcher_config.h" #include "cuttlefish/host/libs/config/file_source.h" #include "cuttlefish/host/libs/image_aggregator/sparse_image.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/host/libs/web/android_build.h" #include "cuttlefish/host/libs/web/android_build_string.h" #include "cuttlefish/host/libs/web/chrome_os_build_string.h" @@ -101,6 +102,8 @@ std::vector GetFetchTargets(const FetchFlags& flags, Result EnsureDirectoriesExist(const std::string& host_tools_directory, const std::string& cache_base_path, const std::vector& targets) { + CF_TRACE_EVENT_FUNC(); + CF_EXPECT(EnsureDirectoryExists(host_tools_directory)); CF_EXPECT(EnsureDirectoryExists(cache_base_path)); for (const auto& target : targets) { @@ -125,6 +128,7 @@ Result> GetBuildHelper( Result GetBuilds(BuildApi& build_api, const BuildStrings& build_sources) { + CF_TRACE_EVENT_FUNC(); Builds result = Builds{ .default_build = CF_EXPECT(GetBuildHelper( build_api, build_sources.default_build, kDefaultBuildTarget)), @@ -203,6 +207,8 @@ Result FetchDefaultTarget(FetchBuildContext& context, bool keep_downloaded_archives, const DownloadFlags& flags, bool has_system_build) { + CF_TRACE_EVENT_FUNC(); + constexpr char kSignedPrefix[] = "signed/signed-"; // Some older builds might not have misc_info.txt, so permit errors on // fetching misc_info.txt @@ -262,6 +268,8 @@ Result FetchDefaultTarget(FetchBuildContext& context, Result FetchSystemTarget(FetchBuildContext& context, bool download_img_zip, const bool keep_downloaded_archives) { + CF_TRACE_EVENT_FUNC(); + std::string target_files_name = context.GetBuildZipName("target_files"); FetchArtifact target_files = context.Artifact(target_files_name); @@ -303,6 +311,8 @@ Result FetchSystemTarget(FetchBuildContext& context, } Result FetchKernelTarget(FetchBuildContext context) { + CF_TRACE_EVENT_FUNC(); + // If the kernel is from an arm/aarch64 build, the artifact will be called // Image. if (!context.Artifact("bzImage").DownloadTo("kernel").ok()) { @@ -318,6 +328,8 @@ Result FetchKernelTarget(FetchBuildContext context) { Result FetchBootTarget(FetchBuildContext& context, bool keep_downloaded_archives) { + CF_TRACE_EVENT_FUNC(); + std::string img_zip = context.GetBuildZipName("img"); std::string to_download = context.GetFilepath().value_or(img_zip); FetchArtifact artifact = context.Artifact(to_download); @@ -335,6 +347,8 @@ Result FetchBootTarget(FetchBuildContext& context, } Result FetchBootloaderTarget(FetchBuildContext& context) { + CF_TRACE_EVENT_FUNC(); + // If the bootloader is from an arm/aarch64 build, the artifact will be of // filetype bin. if (!context.Artifact("u-boot.rom").DownloadTo("bootloader").ok()) { @@ -344,6 +358,8 @@ Result FetchBootloaderTarget(FetchBuildContext& context) { } Result FetchAndroidEfiLoaderTarget(FetchBuildContext& context) { + CF_TRACE_EVENT_FUNC(); + std::string filename = context.GetFilepath().value_or("gbl_x86_64.efi"); CF_EXPECT(context.Artifact(filename).DownloadTo("android_efi_loader.efi")); return {}; @@ -351,6 +367,8 @@ Result FetchAndroidEfiLoaderTarget(FetchBuildContext& context) { Result FetchOtaToolsTarget(FetchBuildContext& context, bool keep_downloaded_archives) { + CF_TRACE_EVENT_FUNC(); + FetchArtifact otatools = context.Artifact("otatools.zip"); CF_EXPECT(otatools.Download()); CF_EXPECT(otatools.ExtractAll()); @@ -362,6 +380,8 @@ Result FetchOtaToolsTarget(FetchBuildContext& context, Result FetchTestSuitesTarget(FetchBuildContext& context, bool keep_downloaded_archives) { + CF_TRACE_EVENT_FUNC(); + FetchArtifact android_cts = context.Artifact("android-cts.zip"); // TODO(b/468074996): determine what tradefed actually needs and potentially // expose a flag to allow downloading specific parts of the entire zip. @@ -379,6 +399,8 @@ Result FetchChromeOsTarget( const TargetDirectories& target_directories, const bool keep_downloaded_archives, FetcherConfig& config, FetchTracer::Trace trace) { + CF_TRACE_EVENT_FUNC(); + auto artifacts_opt = CF_EXPECT(luci_build_api.GetBuildArtifacts(chrome_os_build_string)); auto artifacts = CF_EXPECT(std::move(artifacts_opt)); @@ -404,6 +426,8 @@ Result FetchChromeOsTarget( Result FetchTarget(FetchContext& fetch_context, const DownloadFlags& flags, const bool keep_downloaded_archives) { + CF_TRACE_EVENT_FUNC(); + if (std::optional context = fetch_context.DefaultBuild()) { bool has_system_build = fetch_context.SystemBuild().has_value(); CF_EXPECT(FetchDefaultTarget(*context, keep_downloaded_archives, flags, @@ -447,6 +471,8 @@ Result Fetch(const FetchFlags& flags, const std::string& cache_base_path, const HostToolsTarget& host_target, std::vector& targets) { + CF_TRACE_EVENT_FUNC(); + #ifdef __BIONIC__ // TODO(schuffelen): Find a better way to deal with tzdata setenv("ANDROID_TZDATA_ROOT", "/", /* overwrite */ 0); diff --git a/base/cvd/cuttlefish/host/commands/cvd/main.cc b/base/cvd/cuttlefish/host/commands/cvd/main.cc index 866d48ecdcb..17c2f010cbe 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/main.cc +++ b/base/cvd/cuttlefish/host/commands/cvd/main.cc @@ -40,6 +40,7 @@ #include "cuttlefish/host/commands/cvd/cvd.h" #include "cuttlefish/host/commands/cvd/utils/common.h" #include "cuttlefish/host/commands/cvd/version/version.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/host/libs/vm_manager/host_configuration.h" #include "cuttlefish/posix/strerror.h" // TODO(315772518) Re-enable once metrics send is reenabled @@ -124,6 +125,10 @@ void IncreaseFileLimit() { } Result CvdMain(cvd_common::Args all_args) { + auto scoped_trace_flusher = InitializeTracing(); + + CF_TRACE_EVENT("CvdMain"); + if (!isatty(0)) { LOG(INFO) << GetVersionIds().ToString(); } diff --git a/base/cvd/cuttlefish/host/commands/run_cvd/BUILD.bazel b/base/cvd/cuttlefish/host/commands/run_cvd/BUILD.bazel index 16e84acee80..179bf0e1574 100644 --- a/base/cvd/cuttlefish/host/commands/run_cvd/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/run_cvd/BUILD.bazel @@ -26,6 +26,7 @@ cf_cc_library( "//cuttlefish/host/libs/config:config_utils", "//cuttlefish/host/libs/config:cuttlefish_config", "//cuttlefish/host/libs/feature", + "//cuttlefish/host/libs/tracing", "//cuttlefish/host/libs/vm_manager", "//cuttlefish/posix:strerror", "//cuttlefish/result", @@ -105,6 +106,7 @@ cf_cc_binary( "//cuttlefish/host/libs/config/fastboot", "//cuttlefish/host/libs/feature", "//cuttlefish/host/libs/feature:inject", + "//cuttlefish/host/libs/tracing", "//cuttlefish/host/libs/metrics", "//cuttlefish/host/libs/version", "//cuttlefish/host/libs/vm_manager", @@ -146,6 +148,7 @@ cf_cc_library( "//cuttlefish/host/libs/feature", "//cuttlefish/host/libs/feature:inject", "//cuttlefish/host/libs/process_monitor", + "//cuttlefish/host/libs/tracing", "//cuttlefish/host/libs/vm_manager", "//cuttlefish/posix:strerror", "//cuttlefish/result", diff --git a/base/cvd/cuttlefish/host/commands/run_cvd/boot_state_machine.cc b/base/cvd/cuttlefish/host/commands/run_cvd/boot_state_machine.cc index 9b7d849fbeb..3014bd196d2 100644 --- a/base/cvd/cuttlefish/host/commands/run_cvd/boot_state_machine.cc +++ b/base/cvd/cuttlefish/host/commands/run_cvd/boot_state_machine.cc @@ -62,6 +62,7 @@ #include "cuttlefish/host/libs/config/cuttlefish_config.h" #include "cuttlefish/host/libs/feature/feature.h" #include "cuttlefish/host/libs/feature/kernel_log_pipe_provider.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/host/libs/vm_manager/vm_manager.h" #include "cuttlefish/posix/strerror.h" #include "cuttlefish/result/result.h" @@ -424,6 +425,7 @@ class CvdBootStateMachine : public SetupFeature, public KernelLogPipeConsumer { } void ThreadLoop(SharedFD boot_events_pipe, SharedFD restore_complete_pipe) { + CF_TRACE_EVENT("BootStateMachine WaitForBoot"); while (true) { std::vector poll_shared_fd = { { @@ -597,6 +599,7 @@ class CvdBootStateMachine : public SetupFeature, public KernelLogPipeConsumer { } if ((*read_result)->event == monitor::Event::BootCompleted) { + CF_TRACE_EVENT_INSTANT("BootCompleted"); LOG(INFO) << "Virtual device booted successfully"; state_ |= kGuestBootCompleted; if (!instance_.vcpu_config_path().empty()) { @@ -606,6 +609,7 @@ class CvdBootStateMachine : public SetupFeature, public KernelLogPipeConsumer { } } } else if ((*read_result)->event == monitor::Event::BootFailed) { + CF_TRACE_EVENT_INSTANT("BootFailed"); LOG(ERROR) << "Virtual device failed to boot"; state_ |= kGuestBootFailed; } // Ignore the other signals diff --git a/base/cvd/cuttlefish/host/commands/run_cvd/main.cc b/base/cvd/cuttlefish/host/commands/run_cvd/main.cc index bd36ac1dc79..ad3ced02752 100644 --- a/base/cvd/cuttlefish/host/commands/run_cvd/main.cc +++ b/base/cvd/cuttlefish/host/commands/run_cvd/main.cc @@ -78,6 +78,7 @@ #include "cuttlefish/host/libs/config/fastboot/fastboot.h" #include "cuttlefish/host/libs/feature/feature.h" #include "cuttlefish/host/libs/feature/inject.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/host/libs/metrics/metrics_receiver.h" #include "cuttlefish/host/libs/version/version.h" #include "cuttlefish/host/libs/vm_manager/vm_manager.h" @@ -131,9 +132,15 @@ class InstanceLifecycle : public LateInjected { // One of the setup features can consume most output, so print this early. DiagnosticInformation::PrintAll(diagnostics_); - CF_EXPECT(SetupFeature::RunSetup(setup_features_)); + { + CF_TRACE_EVENT("SetupFeatures"); + CF_EXPECT(SetupFeature::RunSetup(setup_features_)); + } - CF_EXPECT(server_loop_.Run()); + { + CF_TRACE_EVENT("RunServer"); + CF_EXPECT(server_loop_.Run()); + } return {}; } @@ -262,6 +269,11 @@ Result RunCvdMain(int argc, char** argv) { auto instance = config->ForDefaultInstance(); ConfigureLogs(*config, instance); + auto scoped_trace_flusher = InitializeTracing(); + CF_TRACE_EVENT("RunCvd", + "instance", instance.instance_name(), + perfetto::Flow::Global(GetFlowId(instance.instance_name()))); + fruit::Injector<> injector(runCvdComponent, config, &environment, &instance); for (auto& late_injected : injector.getMultibindings()) { diff --git a/base/cvd/cuttlefish/host/commands/run_cvd/server_loop_impl.cpp b/base/cvd/cuttlefish/host/commands/run_cvd/server_loop_impl.cpp index f06a13766af..d3bde6a3fa5 100644 --- a/base/cvd/cuttlefish/host/commands/run_cvd/server_loop_impl.cpp +++ b/base/cvd/cuttlefish/host/commands/run_cvd/server_loop_impl.cpp @@ -50,6 +50,7 @@ #include "cuttlefish/host/libs/config/vmm_mode.h" #include "cuttlefish/host/libs/feature/command_source.h" #include "cuttlefish/host/libs/process_monitor/process_monitor.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/posix/strerror.h" #include "cuttlefish/result/result.h" @@ -59,6 +60,7 @@ namespace run_cvd_impl { bool ServerLoopImpl::CreateQcowOverlay(const std::string& crosvm_path, const std::string& backing_file, const std::string& output_overlay_path) { + CF_TRACE_EVENT_FUNC(); Command crosvm_qcow2_cmd(crosvm_path); crosvm_qcow2_cmd.AddParameter("create_qcow2"); crosvm_qcow2_cmd.AddParameter("--backing-file"); @@ -110,10 +112,13 @@ Result ServerLoopImpl::Run() { snapshot_control_files_->run_cvd_to_secure_env_fd; ProcessMonitor process_monitor(std::move(process_monitor_properties), channel_to_secure_env); - - CF_EXPECT(process_monitor.StartAndMonitorProcesses()); + { + CF_TRACE_EVENT("LaunchSubprocesses"); + CF_EXPECT(process_monitor.StartAndMonitorProcesses()); + } device_status_ = DeviceStatus::kActive; + CF_TRACE_EVENT("WaitForGuestBoot"); while (true) { // TODO: use select to handle simultaneous connections. SharedFDSet read_set; @@ -174,12 +179,14 @@ Result ServerLoopImpl::ResultSetup() { Result ServerLoopImpl::HandleExtended( const LauncherActionInfo& action_info, ProcessMonitor& process_monitor) { + CF_TRACE_EVENT_FUNC(); using ActionsCase = ::cuttlefish::run_cvd::ExtendedLauncherAction::ActionsCase; CF_EXPECT(action_info.action == LauncherAction::kExtended); switch (action_info.extended_action.actions_case()) { case ActionsCase::kSuspend: { + CF_TRACE_EVENT("Suspend"); VLOG(0) << "Run_cvd received suspend request."; if (device_status_.load() == DeviceStatus::kActive) { CF_EXPECT(HandleSuspend(process_monitor)); @@ -188,6 +195,7 @@ Result ServerLoopImpl::HandleExtended( return {}; } case ActionsCase::kResume: { + CF_TRACE_EVENT("Resume"); VLOG(0) << "Run_cvd received resume request."; if (device_status_.load() == DeviceStatus::kSuspended) { CF_EXPECT(HandleResume(process_monitor)); @@ -196,6 +204,7 @@ Result ServerLoopImpl::HandleExtended( return {}; } case ActionsCase::kSnapshotTake: { + CF_TRACE_EVENT("SnapshotTake"); VLOG(0) << "Run_cvd received snapshot request."; CF_EXPECT(device_status_.load() == DeviceStatus::kSuspended, "The device is not suspended, and snapshot cannot be taken"); @@ -204,16 +213,19 @@ Result ServerLoopImpl::HandleExtended( return {}; } case ActionsCase::kStartScreenRecording: { + CF_TRACE_EVENT("StartScreenRecording"); VLOG(0) << "Run_cvd received start screen recording request."; CF_EXPECT(HandleStartScreenRecording()); return {}; } case ActionsCase::kStopScreenRecording: { + CF_TRACE_EVENT("StopScreenRecording"); VLOG(0) << "Run_cvd received stop screen recording request."; CF_EXPECT(HandleStopScreenRecording()); return {}; } case ActionsCase::kScreenshotDisplay: { + CF_TRACE_EVENT("ScreenshotDisplay"); VLOG(0) << "Run_cvd received screenshot display request."; const auto& request = action_info.extended_action.screenshot_display(); CF_EXPECT(HandleScreenshotDisplay(request)); @@ -227,8 +239,10 @@ Result ServerLoopImpl::HandleExtended( void ServerLoopImpl::HandleActionWithNoData(const LauncherAction action, const SharedFD& client, ProcessMonitor& process_monitor) { + CF_TRACE_EVENT_FUNC(); switch (action) { case LauncherAction::kStop: { + CF_TRACE_EVENT("Stop"); auto stop = process_monitor.StopMonitoredProcesses(); if (stop.ok()) { auto response = LauncherResponse::kSuccess; @@ -242,6 +256,7 @@ void ServerLoopImpl::HandleActionWithNoData(const LauncherAction action, break; } case LauncherAction::kFail: { + CF_TRACE_EVENT("Fail"); auto stop = process_monitor.StopMonitoredProcesses(); if (stop.ok()) { auto response = LauncherResponse::kSuccess; @@ -261,6 +276,7 @@ void ServerLoopImpl::HandleActionWithNoData(const LauncherAction action, break; } case LauncherAction::kPowerwash: { + CF_TRACE_EVENT("Powerwash"); LOG(INFO) << "Received a Powerwash request from the monitor socket"; const auto& disks = instance_.virtual_disk_paths(); auto overlay = instance_.PerInstancePath("overlay.img"); @@ -295,6 +311,7 @@ void ServerLoopImpl::HandleActionWithNoData(const LauncherAction action, break; } case LauncherAction::kRestart: { + CF_TRACE_EVENT("Restart"); auto stop = process_monitor.StopMonitoredProcesses(); if (!stop.ok()) { LOG(ERROR) << "Stopping processes failed:\n" << stop.error(); @@ -360,6 +377,8 @@ void ServerLoopImpl::DeleteFifos() { } bool ServerLoopImpl::PowerwashFiles() { + CF_TRACE_EVENT_FUNC(); + DeleteFifos(); // TODO(b/269669405): Figure out why this file is not being deleted @@ -430,6 +449,8 @@ bool ServerLoopImpl::PowerwashFiles() { } void ServerLoopImpl::RestartRunCvd(int notification_fd) { + CF_TRACE_EVENT_FUNC(); + // On device creation, if the file "restore" exists, a restore of the device // occurs. This means a restart will instead perform a restore, which is // undesired behavior. Always try to delete the file "restore" if a restart is diff --git a/base/cvd/cuttlefish/host/commands/start/BUILD.bazel b/base/cvd/cuttlefish/host/commands/start/BUILD.bazel index 1708d41be86..9c320737270 100644 --- a/base/cvd/cuttlefish/host/commands/start/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/start/BUILD.bazel @@ -32,6 +32,7 @@ cf_cc_binary( "//cuttlefish/host/libs/config:fetcher_config", "//cuttlefish/host/libs/config:host_tools_version", "//cuttlefish/host/libs/config:instance_nums", + "//cuttlefish/host/libs/tracing", "//cuttlefish/host/libs/vm_manager", "//libbase", "@abseil-cpp//absl/base:no_destructor", diff --git a/base/cvd/cuttlefish/host/commands/start/main.cc b/base/cvd/cuttlefish/host/commands/start/main.cc index 47e64fe7e80..ddd948e5894 100644 --- a/base/cvd/cuttlefish/host/commands/start/main.cc +++ b/base/cvd/cuttlefish/host/commands/start/main.cc @@ -45,6 +45,7 @@ #include "cuttlefish/host/libs/config/fetcher_config.h" #include "cuttlefish/host/libs/config/host_tools_version.h" #include "cuttlefish/host/libs/config/instance_nums.h" +#include "cuttlefish/host/libs/tracing/tracing.h" #include "cuttlefish/posix/symlink.h" namespace cuttlefish { @@ -206,6 +207,10 @@ Result LinkLogs2InstanceDir( int CvdInternalStartMain(int argc, char** argv) { LogToStderr(); + + auto scoped_trace_flusher = InitializeTracing(); + CF_TRACE_EVENT("cvd_internal_start"); + std::vector args(argv + 1, argv + argc); std::vector assemble_args; @@ -292,15 +297,18 @@ int CvdInternalStartMain(int argc, char** argv) { auto assembler_input = WriteFiles(AvailableFilesReport()); std::string assembler_output; - auto assemble_ret = - InvokeAssembler(assembler_input, assembler_output, - forwarder.ArgvForSubprocess(AssemblerPath(), args)); - - if (assemble_ret != 0) { - LOG(ERROR) << "assemble_cvd returned " << assemble_ret; - return assemble_ret; - } else { - VLOG(0) << "assemble_cvd exited successfully."; + { + CF_TRACE_EVENT("assemble_cvd"); + auto assemble_ret = + InvokeAssembler(assembler_input, assembler_output, + forwarder.ArgvForSubprocess(AssemblerPath(), args)); + + if (assemble_ret != 0) { + LOG(ERROR) << "assemble_cvd returned " << assemble_ret; + return assemble_ret; + } else { + VLOG(0) << "assemble_cvd exited successfully."; + } } std::string conf_path; @@ -326,11 +334,15 @@ int CvdInternalStartMain(int argc, char** argv) { setenv(kCuttlefishInstanceEnvVarName, instance.id().c_str(), /* overwrite */ 1); + CF_TRACE_EVENT("run_cvd", // + "instance", instance.instance_name(), // + perfetto::Flow::Global(GetFlowId(instance.instance_name()))); auto run_proc = StartRunner(std::move(runner_stdin), instance, forwarder.ArgvForSubprocess(RunnerPath())); runners.push_back(std::move(run_proc)); } + CF_TRACE_EVENT("Wait for RunCvd Runners"); bool run_cvd_failure = false; for (auto& run_proc : runners) { auto run_ret = run_proc.Wait(); diff --git a/base/cvd/cuttlefish/host/libs/feature/BUILD.bazel b/base/cvd/cuttlefish/host/libs/feature/BUILD.bazel index 1b9d0276300..825178a6659 100644 --- a/base/cvd/cuttlefish/host/libs/feature/BUILD.bazel +++ b/base/cvd/cuttlefish/host/libs/feature/BUILD.bazel @@ -18,6 +18,7 @@ cf_cc_library( "//cuttlefish/common/libs/fs", "//cuttlefish/common/libs/utils:subprocess", "//cuttlefish/common/libs/utils:type_name", + "//cuttlefish/host/libs/tracing", "//cuttlefish/result", "//libbase", "@abseil-cpp//absl/log", diff --git a/base/cvd/cuttlefish/host/libs/feature/feature.cpp b/base/cvd/cuttlefish/host/libs/feature/feature.cpp index 611e62800ac..89b071bff53 100644 --- a/base/cvd/cuttlefish/host/libs/feature/feature.cpp +++ b/base/cvd/cuttlefish/host/libs/feature/feature.cpp @@ -24,6 +24,7 @@ #include "absl/log/log.h" #include "cuttlefish/result/result.h" +#include "cuttlefish/host/libs/tracing/tracing.h" namespace cuttlefish { @@ -49,6 +50,7 @@ SetupFeature::~SetupFeature() {} "Dependency issue detected, not performing any setup."); // TODO(b/189153501): This can potentially be parallelized. for (auto& feature : ordered_features) { + CF_TRACE_EVENT(perfetto::DynamicString{"FeatureSetup " + feature->Name()}); VLOG(0) << "Running setup for " << feature->Name(); CF_EXPECT(feature->ResultSetup(), "Setup failed for " << feature->Name()); } diff --git a/base/cvd/cuttlefish/host/libs/tracing/BUILD.bazel b/base/cvd/cuttlefish/host/libs/tracing/BUILD.bazel new file mode 100644 index 00000000000..10cf85a9d94 --- /dev/null +++ b/base/cvd/cuttlefish/host/libs/tracing/BUILD.bazel @@ -0,0 +1,18 @@ +load("//cuttlefish/bazel:rules.bzl", "cf_cc_library") + +package( + default_visibility = ["//:android_cuttlefish"], +) + +cf_cc_library( + name = "tracing", + srcs = [ + "tracing.cpp", + ], + hdrs = [ + "tracing.h", + ], + deps = [ + "@perfetto//:libperfetto_client_experimental", + ], +) diff --git a/base/cvd/cuttlefish/host/libs/tracing/README.md b/base/cvd/cuttlefish/host/libs/tracing/README.md new file mode 100644 index 00000000000..9e4990f6115 --- /dev/null +++ b/base/cvd/cuttlefish/host/libs/tracing/README.md @@ -0,0 +1,47 @@ +# Cuttlefish Tracing + +Cuttlefish host tooling supports [Perfetto](http://perfetto.dev) for tracing. + +## Setup + +Please see the +[Perfetto Quickstart](https://perfetto.dev/docs/getting-started/system-tracing) +instructions, or follow these potentially out of date instructions below: + +``` +curl -LO https://get.perfetto.dev/tracebox +chmod +x tracebox +``` + +## Usage + +``` +./tracebox --system-sockets -o cuttlefish_trace.ptrace --txt -c cuttlefish_trace.cfg +``` + +with `cuttlefish_trace.cfg` containing the following or similar: + +``` +buffers { + size_kb: 4096 +} +data_sources { + config { + name: "track_event" + track_event_config { + enabled_categories: "cuttlefish" + } + } +} +``` + +Next, run Cuttlefish: + +``` +cvd create +``` + +Finally, end the trace capture with Ctrl + C. + +You can open https://ui.perfetto.dev/ in your webbrowser and use "Open trace +file" to view the trace. \ No newline at end of file diff --git a/base/cvd/cuttlefish/host/libs/tracing/tracing.cpp b/base/cvd/cuttlefish/host/libs/tracing/tracing.cpp new file mode 100644 index 00000000000..9ba13723c8b --- /dev/null +++ b/base/cvd/cuttlefish/host/libs/tracing/tracing.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cuttlefish/host/libs/tracing/tracing.h" + +#include "perfetto/tracing/core/trace_config.h" + +PERFETTO_TRACK_EVENT_STATIC_STORAGE(); + +namespace cuttlefish { + +ScopedTraceFlusher::~ScopedTraceFlusher() { + CF_TRACE_EVENT_INSTANT("StopTracing"); + perfetto::TrackEvent::Flush(); +} + +ScopedTraceFlusher InitializeTracing() { + []() { + perfetto::TracingInitArgs args; + args.backends |= perfetto::kSystemBackend; + perfetto::Tracing::Initialize(args); + + perfetto::TrackEvent::Register(); + + // Use a startup session to buffer trace events for a short + // period so that trace events that occur after this function + // ends but before the handshake with traced are still captured. + perfetto::TraceConfig startup_trace_config; + startup_trace_config.add_buffers()->set_size_kb(1024); + auto* track_events_data_config = startup_trace_config.add_data_sources()->mutable_config(); + track_events_data_config->set_name("track_event"); + perfetto::protos::gen::TrackEventConfig track_event_config; + track_event_config.add_enabled_categories("cuttlefish"); + track_events_data_config->set_track_event_config_raw(track_event_config.SerializeAsString()); + + perfetto::Tracing::SetupStartupTracingOpts startup_opts; + startup_opts.timeout_ms = 5000; + startup_opts.backend = perfetto::kSystemBackend; + perfetto::Tracing::SetupStartupTracingBlocking(std::move(startup_trace_config), startup_opts); + + CF_TRACE_EVENT_INSTANT("StartTracing"); + }(); + return ScopedTraceFlusher(); +} + +namespace { + +uint64_t BadStableHash(uint64_t hash, char c) { + return (hash << 5) + hash + c; +} + +uint64_t BadStableHash(uint64_t hash, std::string_view str) { + for (char c : str) { + hash = BadStableHash(hash, c); + } + return hash; +} + +uint64_t BadStableHash(std::string_view str) { + constexpr uint64_t kInitialBadStableHash = 5381; + return BadStableHash(kInitialBadStableHash, str); +} + +} // namespace + +uint64_t GetFlowId(std::string_view s) { + return BadStableHash(s); +} + +} // namespace cuttlefish diff --git a/base/cvd/cuttlefish/host/libs/tracing/tracing.h b/base/cvd/cuttlefish/host/libs/tracing/tracing.h new file mode 100644 index 00000000000..79c9456c930 --- /dev/null +++ b/base/cvd/cuttlefish/host/libs/tracing/tracing.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include +#include + +#define CF_TRACE_CATEGORY "cuttlefish" + +PERFETTO_DEFINE_CATEGORIES(perfetto::Category(CF_TRACE_CATEGORY) + .SetDescription("Cuttlefish Events") + .SetTags(CF_TRACE_CATEGORY)); + +#define CF_TRACE_EVENT(...) \ + TRACE_EVENT(CF_TRACE_CATEGORY, __VA_ARGS__) + +#define CF_TRACE_EVENT_INSTANT(...) \ + TRACE_EVENT_INSTANT(CF_TRACE_CATEGORY, __VA_ARGS__) + +#define CF_TRACE_EVENT_FUNC() \ + TRACE_EVENT(CF_TRACE_CATEGORY, __PRETTY_FUNCTION__) + +namespace cuttlefish { + +class ScopedTraceFlusher { + public: + ScopedTraceFlusher() = default; + ~ScopedTraceFlusher(); +}; + +// Performs any initialization required for tracing. +ScopedTraceFlusher InitializeTracing(); + +// Effectively a very basic hash since std::hash is not guaranteed +// to be stable across difference program executions. +uint64_t GetFlowId(std::string_view s); + +} // cuttlefish \ No newline at end of file