Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
handle_exception.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "handle_exception.h"
6
7#include <fuchsia/feedback/cpp/fidl.h>
8#include <fuchsia/mem/cpp/fidl.h>
9#include <lib/zx/vmo.h>
10#include <sys/types.h>
11#include <zircon/status.h>
12
13#include <string>
14
15#include "flutter/fml/logging.h"
17
18namespace {
19static bool SetStackTrace(const std::string& data,
20 fuchsia::feedback::RuntimeCrashReport* report) {
21 uint64_t num_bytes = data.size();
22 zx::vmo vmo;
23
24 if (zx::vmo::create(num_bytes, 0u, &vmo) < 0) {
25 return false;
26 }
27
28 if (num_bytes > 0) {
29 if (vmo.write(data.data(), 0, num_bytes) < 0) {
30 return false;
31 }
32 }
33
34 fuchsia::mem::Buffer buffer;
35 buffer.vmo = std::move(vmo);
36 buffer.size = num_bytes;
37 report->set_exception_stack_trace(std::move(buffer));
38
39 return true;
40}
41
42fuchsia::feedback::CrashReport BuildCrashReport(
43 const std::string& component_url,
44 const std::string& error,
45 const std::string& stack_trace) {
46 // The runtime type has already been pre-pended to the error message so we
47 // expect the format to be '$RuntimeType: $Message'.
48 std::string error_type;
49 std::string error_message;
50 const size_t delimiter_pos = error.find_first_of(':');
51 if (delimiter_pos == std::string::npos) {
52 FML_LOG(ERROR) << "error parsing Dart exception: expected format "
53 "'$RuntimeType: $Message', got '"
54 << error << "'";
55 // We still need to specify a type, otherwise the stack trace does not
56 // show up in the crash server UI.
57 error_type = "UnknownError";
58 error_message = error;
59 } else {
60 error_type = error.substr(0, delimiter_pos);
61 error_message =
62 error.substr(delimiter_pos + 2 /*to get rid of the leading ': '*/);
63 }
64
65 // Truncate error message to the maximum length allowed for the crash_reporter
66 // FIDL call
67 error_message = error_message.substr(
68 0, fuchsia::feedback::MAX_EXCEPTION_MESSAGE_LENGTH - 1);
69
70 fuchsia::feedback::RuntimeCrashReport dart_report;
71 dart_report.set_exception_type(error_type);
72 dart_report.set_exception_message(error_message);
73 if (!SetStackTrace(stack_trace, &dart_report)) {
74 FML_LOG(ERROR) << "Failed to convert Dart stack trace to VMO";
75 }
76
77 fuchsia::feedback::SpecificCrashReport specific_report;
78 specific_report.set_dart(std::move(dart_report));
79 fuchsia::feedback::CrashReport report;
80 report.set_program_name(component_url);
81 report.set_specific_report(std::move(specific_report));
82 report.set_is_fatal(false);
83 return report;
84}
85
86} // namespace
87
88namespace dart_utils {
89
90void HandleIfException(std::shared_ptr<::sys::ServiceDirectory> services,
91 const std::string& component_url,
94 return;
95 }
96
97 const std::string error =
99 const std::string stack_trace =
101
102 return HandleException(services, component_url, error, stack_trace);
103}
104
105void HandleException(std::shared_ptr<::sys::ServiceDirectory> services,
106 const std::string& component_url,
107 const std::string& error,
108 const std::string& stack_trace) {
109 fuchsia::feedback::CrashReport crash_report =
110 BuildCrashReport(component_url, error, stack_trace);
111
112 fuchsia::feedback::CrashReporterPtr crash_reporter =
113 services->Connect<fuchsia::feedback::CrashReporter>();
114 crash_reporter->FileReport(
115 std::move(crash_report),
116 [](fuchsia::feedback::CrashReporter_FileReport_Result result) {
117 if (result.is_err()) {
118 FML_LOG(ERROR) << "Failed to report Dart exception: "
119 << static_cast<uint32_t>(result.err());
120 }
121 });
122}
123
124} // namespace dart_utils
DART_EXPORT Dart_Handle Dart_ErrorGetStackTrace(Dart_Handle handle)
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
DART_EXPORT Dart_Handle Dart_ErrorGetException(Dart_Handle handle)
DART_EXPORT bool Dart_ErrorHasException(Dart_Handle handle)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_ToString(Dart_Handle object)
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
#define FML_LOG(severity)
Definition logging.h:82
void HandleIfException(std::shared_ptr<::sys::ServiceDirectory > services, const std::string &component_url, Dart_Handle result)
void HandleException(std::shared_ptr<::sys::ServiceDirectory > services, const std::string &component_url, const std::string &error, const std::string &stack_trace)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
std::string StdStringFromDart(Dart_Handle handle)
#define ERROR(message)