| // Copyright 2018 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/crashpad_agent/report_attachments.h" |
| |
| #include <fuchsia/mem/cpp/fidl.h> |
| #include <lib/syslog/cpp/logger.h> |
| #include <zircon/errors.h> |
| |
| #include <memory> |
| #include <string> |
| |
| #include "third_party/crashpad/minidump/minidump_file_writer.h" |
| #include "third_party/crashpad/util/file/file_writer.h" |
| |
| namespace fuchsia { |
| namespace crash { |
| |
| namespace { |
| |
| // The crash server expects a specific filename for the attached stack trace in |
| // Dart crash reports. |
| const char kAttachmentDartStackTraceFilename[] = "DartError"; |
| |
| bool WriteVMO(crashpad::FileWriter* writer, const fuchsia::mem::Buffer& vmo) { |
| // TODO(frousseau): make crashpad::FileWriter VMO-aware. |
| auto data = std::make_unique<uint8_t[]>(vmo.size); |
| if (vmo.vmo.read(data.get(), 0u, vmo.size) != ZX_OK) { |
| return false; |
| } |
| return writer->Write(data.get(), vmo.size); |
| } |
| |
| bool AddAttachment(crashpad::CrashReportDatabase::NewReport* report, |
| const std::string& attachment_filename, |
| const fuchsia::mem::Buffer& attachment_content) { |
| crashpad::FileWriter* writer = report->AddAttachment(attachment_filename); |
| if (!writer) { |
| return false; |
| } |
| if (!WriteVMO(writer, std::move(attachment_content))) { |
| FX_LOGS(ERROR) << "error writing " << attachment_filename << " to file"; |
| return false; |
| } |
| return true; |
| } |
| |
| void AddFeedbackAttachments(crashpad::CrashReportDatabase::NewReport* report, |
| const fuchsia::feedback::Data& feedback_data) { |
| if (!feedback_data.has_attachments()) { |
| return; |
| } |
| for (const auto& attachment : feedback_data.attachments()) { |
| AddAttachment(report, attachment.key, attachment.value); |
| } |
| } |
| |
| } // namespace |
| |
| void AddManagedRuntimeExceptionAttachments( |
| crashpad::CrashReportDatabase::NewReport* report, |
| const fuchsia::feedback::Data& feedback_data, |
| ManagedRuntimeException* exception) { |
| AddFeedbackAttachments(report, feedback_data); |
| |
| // Language-specific attachments. |
| switch (exception->Which()) { |
| case ManagedRuntimeException::Tag::Invalid: |
| FX_LOGS(ERROR) << "invalid ManagedRuntimeException"; |
| break; |
| case ManagedRuntimeException::Tag::kUnknown_: |
| AddAttachment(report, "data", exception->unknown_().data); |
| break; |
| case ManagedRuntimeException::Tag::kDart: |
| AddAttachment(report, kAttachmentDartStackTraceFilename, |
| exception->dart().stack_trace); |
| break; |
| } |
| } |
| |
| void AddKernelPanicAttachments(crashpad::CrashReportDatabase::NewReport* report, |
| const fuchsia::feedback::Data& feedback_data, |
| fuchsia::mem::Buffer crash_log) { |
| AddFeedbackAttachments(report, feedback_data); |
| AddAttachment(report, "kernel_panic_crash_log", std::move(crash_log)); |
| } |
| |
| } // namespace crash |
| } // namespace fuchsia |