forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Copy //runtime/dart/utils from Topaz into the engine. (flutter#8871)
Build rules and include paths have been updated as necessary. No other functional change.
- Loading branch information
1 parent
149b7b8
commit d717044
Showing
15 changed files
with
714 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# 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. | ||
|
||
assert(is_fuchsia) | ||
|
||
import("//build/fuchsia/sdk.gni") | ||
|
||
config("utils_config") { | ||
include_dirs = [ "../../.." ] | ||
} | ||
|
||
source_set("utils") { | ||
sources = [ | ||
"files.cc", | ||
"files.h", | ||
"handle_exception.cc", | ||
"handle_exception.h", | ||
"inlines.h", | ||
"logging.h", | ||
"tempfs.cc", | ||
"tempfs.h", | ||
"vmo.cc", | ||
"vmo.h", | ||
"vmservice_object.cc", | ||
"vmservice_object.h", | ||
] | ||
|
||
deps = [ | ||
"$fuchsia_sdk_root/fidl:fuchsia.crash", | ||
"$fuchsia_sdk_root/fidl:fuchsia.mem", | ||
"$fuchsia_sdk_root/pkg:async-loop", | ||
"$fuchsia_sdk_root/pkg:async-loop-cpp", | ||
"$fuchsia_sdk_root/pkg:fdio", | ||
"$fuchsia_sdk_root/pkg:memfs", | ||
"$fuchsia_sdk_root/pkg:syslog", | ||
"$fuchsia_sdk_root/pkg:zx", | ||
"$fuchsia_sdk_root/pkg/lib/sys/cpp", | ||
"$fuchsia_sdk_root/pkg/lib/vfs/cpp", | ||
"//third_party/tonic", | ||
] | ||
|
||
public_configs = [ ":utils_config" ] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Copyright 2013 The Flutter 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 "runtime/dart/utils/files.h" | ||
|
||
#include <fcntl.h> | ||
#include <stdint.h> | ||
|
||
#include "runtime/dart/utils/inlines.h" | ||
#include "runtime/dart/utils/logging.h" | ||
|
||
namespace dart_utils { | ||
|
||
namespace { | ||
|
||
bool ReadFileDescriptor(int fd, std::string* result) { | ||
DEBUG_CHECK(result, LOG_TAG, ""); | ||
result->clear(); | ||
|
||
if (fd < 0) { | ||
return false; | ||
} | ||
|
||
constexpr size_t kBufferSize = 1 << 16; | ||
size_t offset = 0; | ||
ssize_t bytes_read = 0; | ||
do { | ||
offset += bytes_read; | ||
result->resize(offset + kBufferSize); | ||
bytes_read = read(fd, &(*result)[offset], kBufferSize); | ||
} while (bytes_read > 0); | ||
|
||
if (bytes_read < 0) { | ||
result->clear(); | ||
return false; | ||
} | ||
|
||
result->resize(offset + bytes_read); | ||
return true; | ||
} | ||
|
||
bool WriteFileDescriptor(int fd, const char* data, ssize_t size) { | ||
ssize_t total = 0; | ||
for (ssize_t partial = 0; total < size; total += partial) { | ||
partial = write(fd, data + total, size - total); | ||
if (partial < 0) | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
} // namespace | ||
|
||
bool ReadFileToString(const std::string& path, std::string* result) { | ||
return ReadFileToStringAt(AT_FDCWD, path, result); | ||
} | ||
|
||
bool ReadFileToStringAt(int dirfd, | ||
const std::string& path, | ||
std::string* result) { | ||
int fd = openat(dirfd, path.c_str(), O_RDONLY); | ||
bool status = ReadFileDescriptor(fd, result); | ||
close(fd); | ||
return status; | ||
} | ||
|
||
bool WriteFile(const std::string& path, const char* data, ssize_t size) { | ||
int fd = openat(AT_FDCWD, path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0666); | ||
if (fd < 0) { | ||
return false; | ||
} | ||
bool status = WriteFileDescriptor(fd, data, size); | ||
close(fd); | ||
return status; | ||
} | ||
|
||
} // namespace dart_utils |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_RUNTIME_DART_UTILS_FILES_H_ | ||
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_RUNTIME_DART_UTILS_FILES_H_ | ||
|
||
#include <string> | ||
|
||
namespace dart_utils { | ||
|
||
// Reads the contents of the file at the given path or file descriptor and | ||
// stores the data in result. Returns true if the file was read successfully, | ||
// otherwise returns false. If this function returns false, |result| will be | ||
// the empty string. | ||
bool ReadFileToString(const std::string& path, std::string* result); | ||
bool ReadFileToStringAt(int dirfd, | ||
const std::string& path, | ||
std::string* result); | ||
|
||
// Writes the given data to the file at the given path. Returns true if the data | ||
// was successfully written, otherwise returns false. | ||
bool WriteFile(const std::string& path, const char* data, ssize_t size); | ||
|
||
} // namespace dart_utils | ||
|
||
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_RUNTIME_DART_UTILS_FILES_H_ |
139 changes: 139 additions & 0 deletions
139
shell/platform/fuchsia/runtime/dart/utils/handle_exception.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
// Copyright 2013 The Flutter 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 "runtime/dart/utils/handle_exception.h" | ||
|
||
#include <string> | ||
|
||
#include <fuchsia/crash/cpp/fidl.h> | ||
#include <fuchsia/mem/cpp/fidl.h> | ||
#include <lib/syslog/global.h> | ||
#include <lib/zx/vmo.h> | ||
#include <sys/types.h> | ||
#include <third_party/tonic/converter/dart_converter.h> | ||
#include <zircon/errors.h> | ||
#include <zircon/status.h> | ||
|
||
#include "runtime/dart/utils/logging.h" | ||
|
||
namespace { | ||
static bool FillBuffer(const std::string& data, fuchsia::mem::Buffer* buffer) { | ||
uint64_t num_bytes = data.size(); | ||
zx::vmo vmo; | ||
|
||
if (zx::vmo::create(num_bytes, 0u, &vmo) < 0) { | ||
return false; | ||
} | ||
|
||
if (num_bytes > 0) { | ||
if (vmo.write(data.data(), 0, num_bytes) < 0) { | ||
return false; | ||
} | ||
} | ||
|
||
buffer->vmo = std::move(vmo); | ||
buffer->size = num_bytes; | ||
|
||
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( | ||
const std::string& error, | ||
const std::string& stack_trace) { | ||
// The runtime type has already been pre-pended to the error message so we | ||
// expect the format to be '$RuntimeType: $Message'. | ||
std::string error_type; | ||
std::string error_message; | ||
const size_t delimiter_pos = error.find_first_of(':'); | ||
if (delimiter_pos == std::string::npos) { | ||
FX_LOGF(ERROR, LOG_TAG, | ||
"error parsing Dart exception: expected format '$RuntimeType: " | ||
"$Message', got '%s'", | ||
error.c_str()); | ||
// We still need to specify a type, otherwise the stack trace does not | ||
// show up in the crash server UI. | ||
error_type = "UnknownError"; | ||
error_message = error; | ||
} else { | ||
error_type = error.substr(0, delimiter_pos); | ||
error_message = | ||
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)) { | ||
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; | ||
} | ||
|
||
} // namespace | ||
|
||
namespace dart_utils { | ||
|
||
zx_status_t HandleIfException(std::shared_ptr<::sys::ServiceDirectory> services, | ||
const std::string& component_url, | ||
Dart_Handle result) { | ||
if (!Dart_IsError(result) || !Dart_ErrorHasException(result)) { | ||
return ZX_OK; | ||
} | ||
|
||
const std::string error = | ||
tonic::StdStringFromDart(Dart_ToString(Dart_ErrorGetException(result))); | ||
const std::string stack_trace = | ||
tonic::StdStringFromDart(Dart_ToString(Dart_ErrorGetStackTrace(result))); | ||
|
||
return HandleException(services, component_url, error, stack_trace); | ||
} | ||
|
||
zx_status_t 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::AnalyzerSyncPtr analyzer; | ||
services->Connect(analyzer.NewRequest()); | ||
#ifndef NDEBUG | ||
if (!analyzer) { | ||
FX_LOG(FATAL, LOG_TAG, "Could not connect to analyzer service"); | ||
} | ||
#endif | ||
|
||
fuchsia::crash::Analyzer_OnManagedRuntimeException_Result out_result; | ||
const zx_status_t status = analyzer->OnManagedRuntimeException( | ||
component_url, std::move(exception), &out_result); | ||
if (status != ZX_OK) { | ||
FX_LOGF(ERROR, LOG_TAG, "Failed to connect to crash analyzer: %d (%s)", | ||
status, zx_status_get_string(status)); | ||
return ZX_ERR_INTERNAL; | ||
} else if (out_result.is_err()) { | ||
FX_LOGF(ERROR, LOG_TAG, "Failed to handle Dart exception: %d (%s)", | ||
out_result.err(), zx_status_get_string(out_result.err())); | ||
return ZX_ERR_INTERNAL; | ||
} | ||
return ZX_OK; | ||
} | ||
|
||
} // namespace dart_utils |
34 changes: 34 additions & 0 deletions
34
shell/platform/fuchsia/runtime/dart/utils/handle_exception.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_RUNTIME_DART_UTILS_HANDLE_EXCEPTION_H_ | ||
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_RUNTIME_DART_UTILS_HANDLE_EXCEPTION_H_ | ||
|
||
#include <memory> | ||
#include <string> | ||
|
||
#include <lib/sys/cpp/service_directory.h> | ||
#include <sys/types.h> | ||
#include <third_party/dart/runtime/include/dart_api.h> | ||
|
||
namespace dart_utils { | ||
|
||
// If |result| is a Dart Exception, passes the exception message and stack trace | ||
// to the crash analyzer service for further handling. | ||
// | ||
// Otherwise early returns with OK status. | ||
zx_status_t HandleIfException(std::shared_ptr<::sys::ServiceDirectory> services, | ||
const std::string& component_url, | ||
Dart_Handle result); | ||
|
||
// Passes the exception message and stack trace to the crash analyzer service | ||
// for further handling. | ||
zx_status_t HandleException(std::shared_ptr<::sys::ServiceDirectory> services, | ||
const std::string& component_url, | ||
const std::string& error, | ||
const std::string& stack_trace); | ||
|
||
} // namespace dart_utils | ||
|
||
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_RUNTIME_DART_UTILS_HANDLE_EXCEPTION_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_RUNTIME_DART_UTILS_INLINES_H_ | ||
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_RUNTIME_DART_UTILS_INLINES_H_ | ||
|
||
#include <lib/syslog/global.h> | ||
|
||
namespace dart_utils { | ||
|
||
inline void Check(bool condition, const char* tag, const char* message = "") { | ||
if (!condition) { | ||
FX_LOG(FATAL, tag, message); | ||
} | ||
} | ||
|
||
#ifndef NDEBUG | ||
#define DEBUG_CHECK(condition, tag, message) \ | ||
dart_utils::Check(condition, tag, message) | ||
#else | ||
#define DEBUG_CHECK(condition, tag, message) (true || (condition)) | ||
#endif | ||
|
||
template <size_t SIZE, typename T> | ||
inline size_t ArraySize(T (&array)[SIZE]) { | ||
return SIZE; | ||
} | ||
|
||
} // namespace dart_utils | ||
|
||
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_RUNTIME_DART_UTILS_INLINES_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_RUNTIME_DART_UTILS_LOGGING_H_ | ||
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_RUNTIME_DART_UTILS_LOGGING_H_ | ||
|
||
namespace dart_utils { | ||
|
||
// Use to mark logs published via the syslog API. | ||
#define LOG_TAG "dart-utils" | ||
|
||
} // namespace dart_utils | ||
|
||
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_RUNTIME_DART_UTILS_LOGGING_H_ |
Oops, something went wrong.