Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion shell/platform/fuchsia/runtime/dart/utils/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ source_set("utils") {
]

deps = [
"$fuchsia_sdk_root/fidl:fuchsia.crash",
"$fuchsia_sdk_root/fidl:fuchsia.feedback",
"$fuchsia_sdk_root/fidl:fuchsia.mem",
"$fuchsia_sdk_root/pkg:async-loop",
"$fuchsia_sdk_root/pkg:async-loop-cpp",
Expand Down
69 changes: 28 additions & 41 deletions shell/platform/fuchsia/runtime/dart/utils/handle_exception.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include "runtime/dart/utils/handle_exception.h"

#include <fuchsia/crash/cpp/fidl.h>
#include <fuchsia/feedback/cpp/fidl.h>
#include <fuchsia/mem/cpp/fidl.h>
#include <lib/syslog/global.h>
#include <lib/zx/vmo.h>
Expand All @@ -17,7 +17,8 @@
#include "runtime/dart/utils/logging.h"

namespace {
static bool FillBuffer(const std::string& data, fuchsia::mem::Buffer* buffer) {
static bool SetStackTrace(const std::string& data,
fuchsia::feedback::RuntimeCrashReport* report) {
uint64_t num_bytes = data.size();
zx::vmo vmo;

Expand All @@ -31,25 +32,16 @@ static bool FillBuffer(const std::string& data, fuchsia::mem::Buffer* buffer) {
}
}

buffer->vmo = std::move(vmo);
buffer->size = num_bytes;
fuchsia::mem::Buffer buffer;
buffer.vmo = std::move(vmo);
buffer.size = num_bytes;
report->set_exception_stack_trace(std::move(buffer));

return true;
}

template <typename T, size_t N>
void CopyToArray(const std::string& s, std::array<T, N>* arr) {
const size_t max_size = arr->size();
auto end = s.end();
if (s.size() > max_size) {
FX_LOGF(WARNING, LOG_TAG, "truncating '%s' to %d characters", s.c_str(),
max_size);
end = s.begin() + max_size;
}
std::copy(s.begin(), end, arr->data());
}

fuchsia::crash::ManagedRuntimeException BuildException(
fuchsia::feedback::CrashReport BuildCrashReport(
const std::string& component_url,
const std::string& error,
const std::string& stack_trace) {
// The runtime type has already been pre-pended to the error message so we
Expand All @@ -72,18 +64,19 @@ fuchsia::crash::ManagedRuntimeException BuildException(
error.substr(delimiter_pos + 2 /*to get rid of the leading ': '*/);
}

// Default-initialize to initialize the underlying arrays of characters with
// 0s and null-terminate the strings.
fuchsia::crash::GenericException exception = {};
CopyToArray(error_type, &exception.type);
CopyToArray(error_message, &exception.message);
if (!FillBuffer(stack_trace, &exception.stack_trace)) {
fuchsia::feedback::RuntimeCrashReport dart_report;
dart_report.set_exception_type(error_type);
dart_report.set_exception_message(error_message);
if (!SetStackTrace(stack_trace, &dart_report)) {
FX_LOG(ERROR, LOG_TAG, "Failed to convert Dart stack trace to VMO");
}

fuchsia::crash::ManagedRuntimeException dart_exception;
dart_exception.set_dart(std::move(exception));
return dart_exception;
fuchsia::feedback::SpecificCrashReport specific_report;
specific_report.set_dart(std::move(dart_report));
fuchsia::feedback::CrashReport report;
report.set_program_name(component_url);
report.set_specific_report(std::move(specific_report));
return report;
}

} // namespace
Expand All @@ -109,22 +102,16 @@ void HandleException(std::shared_ptr<::sys::ServiceDirectory> services,
const std::string& component_url,
const std::string& error,
const std::string& stack_trace) {
fuchsia::crash::ManagedRuntimeException exception =
BuildException(error, stack_trace);

fuchsia::crash::AnalyzerPtr analyzer =
services->Connect<fuchsia::crash::Analyzer>();
#ifndef NDEBUG
if (!analyzer) {
FX_LOG(FATAL, LOG_TAG, "Could not connect to analyzer service");
}
#endif

analyzer->OnManagedRuntimeException(
component_url, std::move(exception),
[](fuchsia::crash::Analyzer_OnManagedRuntimeException_Result result) {
fuchsia::feedback::CrashReport crash_report =
BuildCrashReport(component_url, error, stack_trace);

fuchsia::feedback::CrashReporterPtr crash_reporter =
services->Connect<fuchsia::feedback::CrashReporter>();
crash_reporter->File(
std::move(crash_report),
[](fuchsia::feedback::CrashReporter_File_Result result) {
if (result.is_err()) {
FX_LOGF(ERROR, LOG_TAG, "Failed to handle Dart exception: %d (%s)",
FX_LOGF(ERROR, LOG_TAG, "Failed to report Dart exception: %d (%s)",
result.err(), zx_status_get_string(result.err()));
}
});
Expand Down