From 448d2d90da8705056afb49fb96cb0aa87c825d17 Mon Sep 17 00:00:00 2001 From: bsheedy Date: Fri, 24 Feb 2023 14:22:31 -0800 Subject: [PATCH] Add dump_minidump_annotations Adds the dump_minidump_annotations tool (modified from jperaza's WIP code). This works similarly to Breakpad's minidump_dump tool, but: 1. Is available on Windows 2. Only dumps simple/vectored annotations and annotation objects instead of the entire minidump contents. Current use case for this is to be able to get a minidump's process type on Windows without having to go through symbolization, but there may be other use cases in the future. Bug: chromium:1006331 Change-Id: I392024e230c10ea18673b3cf0d0ad4793d21f5eb Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/4287994 Reviewed-by: Joshua Peraza Commit-Queue: Brian Sheedy --- tools/BUILD.gn | 16 ++++ tools/dump_minidump_annotations.cc | 147 +++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 tools/dump_minidump_annotations.cc diff --git a/tools/BUILD.gn b/tools/BUILD.gn index 4c5d446b..3a042edd 100644 --- a/tools/BUILD.gn +++ b/tools/BUILD.gn @@ -25,6 +25,22 @@ source_set("tool_support") { deps = [ "$mini_chromium_source_parent:base" ] } +crashpad_executable("dump_minidump_annotations") { + sources = [ "dump_minidump_annotations.cc" ] + + deps = [ + ":tool_support", + "../client", + "../snapshot", + "../util", + ] + + if (crashpad_is_win) { + cflags = + [ "/wd4201" ] # nonstandard extension used : nameless struct/union + } +} + if (!crashpad_is_ios) { crashpad_executable("crashpad_database_util") { sources = [ "crashpad_database_util.cc" ] diff --git a/tools/dump_minidump_annotations.cc b/tools/dump_minidump_annotations.cc new file mode 100644 index 00000000..1c26c1b3 --- /dev/null +++ b/tools/dump_minidump_annotations.cc @@ -0,0 +1,147 @@ +// Copyright 2023 The Crashpad Authors +// +// 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 + +#include "base/files/file_path.h" +#include "client/annotation.h" +#include "util/file/file_reader.h" +#include "snapshot/minidump/process_snapshot_minidump.h" +#include "tools/tool_support.h" + +namespace crashpad { +namespace { + +void Usage(const base::FilePath& me) { + // clang-format off + fprintf(stderr, +"Usage: %" PRFilePath " [OPTION]... PATH\n" +"Dump annotations from minidumps.\n" +"\n" +" --help display this help and exit\n" +" --version output version information and exit\n", + me.value().c_str()); + // clang-format on + ToolSupport::UsageTail(me); +} + +struct Options { + const char* minidump; +}; + +int DumpMinidumpAnnotationsMain(int argc, char* argv[]) { + const base::FilePath argv0( + ToolSupport::CommandLineArgumentToFilePathStringType(argv[0])); + const base::FilePath me(argv0.BaseName()); + + enum OptionFlags { + // Long options without short equivalents. + kOptionLastChar = 255, + kOptionMinidump, + + // Standard options. + kOptionHelp = -2, + kOptionVersion = -3, + }; + + static constexpr option long_options[] = { + {"minidump", required_argument, nullptr, kOptionMinidump}, + {"help", no_argument, nullptr, kOptionHelp}, + {"version", no_argument, nullptr, kOptionVersion}, + {nullptr, 0, nullptr, 0}, + }; + + Options options = {}; + + int opt; + while ((opt = getopt_long(argc, argv, "", long_options, nullptr)) != -1) { + switch (opt) { + case kOptionMinidump: { + options.minidump = optarg; + break; + } + case kOptionHelp: { + Usage(me); + return EXIT_SUCCESS; + } + case kOptionVersion: { + ToolSupport::Version(me); + return EXIT_SUCCESS; + } + default: { + ToolSupport::UsageHint(me, nullptr); + return EXIT_FAILURE; + } + } + } + argc -= optind; + argv += optind; + + if (!options.minidump) { + ToolSupport::UsageHint(me, "--minidump is required"); + return EXIT_FAILURE; + } + + FileReader reader; + if (!reader.Open(base::FilePath( + ToolSupport::CommandLineArgumentToFilePathStringType( + options.minidump)))) { + return EXIT_FAILURE; + } + + ProcessSnapshotMinidump snapshot; + if (!snapshot.Initialize(&reader)) { + return EXIT_FAILURE; + } + + for (const ModuleSnapshot* module : snapshot.Modules()) { + printf("Module: %s\n", module->Name().c_str()); + printf(" Simple Annotations\n"); + for (const auto& kv : module->AnnotationsSimpleMap()) { + printf(" simple_annotations[\"%s\"] = %s\n", + kv.first.c_str(), kv.second.c_str()); + } + + printf(" Vectored Annotations\n"); + int index = 0; + for (const std::string& annotation : module->AnnotationsVector()) { + printf(" vectored_annotations[%d] = %s\n", index, annotation.c_str()); + index++; + } + + printf(" Annotation Objects\n"); + for (const AnnotationSnapshot& annotation : module->AnnotationObjects()) { + printf(" annotation_objects[\"%s\"] = ", annotation.name.c_str()); + if (annotation.type != static_cast(Annotation::Type::kString)) { + + printf("\n"); + continue; + } + + std::string value(reinterpret_cast(annotation.value.data()), + annotation.value.size()); + + printf("%s\n", value.c_str()); + } + } + + return EXIT_SUCCESS; +} + +} // namespace +} // namespace crashpad + +int main(int argc, char* argv[]) { + return crashpad::DumpMinidumpAnnotationsMain(argc, argv); +}