Skip to content

Commit

Permalink
[vm] Integrate dart binary with Crashpad on Windows.
Browse files Browse the repository at this point in the history
dart binary would instantiate CrashpadClient if DART_CRASHPAD_HANDLER
and DART_CRASHPAD_CRASHES_DIR environment variables are set.

- DART_CRASHPAD_HANDLER should contain the path to the crashpad_handler
binary that would handle the crash and write minidump;
- DART_CRASHPAD_CRASHES_DIR should contain the path to the crashpad database
which would be used to store minidumps.

Rewrite --copy-crash-dumps support on windows to use Crashpad integration
instead of editing Windows registry.

Embedding crashpad required to roll a new zlib version because Crashpad
depends on the zlib. This version of zlib is buildable with its own
BUILD.gn so our custom BUILD.gn is removed.

Change-Id: I048aad16b234e1d750f0a24782b04e3b6e19703d
Reviewed-on: https://dart-review.googlesource.com/c/81007
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
  • Loading branch information
mraleph authored and commit-bot@chromium.org committed Oct 24, 2018
1 parent b9999b6 commit 2c83eb5
Show file tree
Hide file tree
Showing 15 changed files with 380 additions and 185 deletions.
25 changes: 20 additions & 5 deletions DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ vars = {
"web_socket_channel_tag": "1.0.9",
"WebCore_rev": "fb11e887f77919450e497344da570d780e078bc8",
"yaml_tag": "2.1.15",
"zlib_rev": "c3d0a6190f2f8c924a05ab6cc97b8f975bddd33f",
"zlib_rev": "c44fb7248079cc3d5563b14b3f758aee60d6b415",
"crashpad_rev": "bf327d8ceb6a669607b0dbab5a83a275d03f99ed",
"minichromium_rev": "8d641e30a8b12088649606b912c2bc4947419ccc",
"googletest_rev": "f854f1d27488996dc8a6db3c9453f80b02585e12",
}

deps = {
Expand Down Expand Up @@ -376,11 +379,23 @@ deps = {
"@" + Var("web_socket_channel_tag"),
Var("dart_root") + "/third_party/pkg/yaml":
Var("dart_git") + "yaml.git" + "@" + Var("yaml_tag"),
Var("dart_root") + "/third_party/cygwin": {
"url": Var("chromium_git") + "/chromium/deps/cygwin.git" + "@" +
}

deps_os = {
"win": {
Var("dart_root") + "/third_party/cygwin":
Var("chromium_git") + "/chromium/deps/cygwin.git" + "@" +
"c89e446b273697fadf3a10ff1007a97c0b7de6df",
"condition": "checkout_win",
},
Var("dart_root") + "/third_party/crashpad/crashpad":
Var("chromium_git") + "/crashpad/crashpad.git" + "@" +
Var("crashpad_rev"),
Var("dart_root") + "/third_party/mini_chromium/mini_chromium":
Var("chromium_git") + "/chromium/mini_chromium" + "@" +
Var("minichromium_rev"),
Var("dart_root") + "/third_party/googletest":
Var("fuchsia_git") + "/third_party/googletest" + "@" +
Var("googletest_rev"),
}
}

# TODO(iposva): Move the necessary tools so that hooks can be run
Expand Down
3 changes: 3 additions & 0 deletions build/config/BUILDCONFIG.gn
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ if (is_debug) {
}
_native_compiler_configs += [ _default_optimization_config ]

# zlib's BUILD.gn expects to have this config among default configs.
_native_compiler_configs += [ "//build/config/compiler:default_optimization" ]

# Symbol setup.
_default_symbols_config = "//build/config/compiler:symbols"
_native_compiler_configs += [ _default_symbols_config ]
Expand Down
7 changes: 7 additions & 0 deletions build/config/compiler/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,13 @@ config("no_optimize") {
}
}

# These are two named configs that zlib's BUILD.gn expects to exist.
config("default_optimization") {
}

config("optimize_speed") {
}

# Symbols ----------------------------------------------------------------------

config("symbols") {
Expand Down
3 changes: 0 additions & 3 deletions build/config/win/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ config("common_linker_setup") {
# exceeds maximum allowable size (80000000)
# which started happening more regularly after VS2013 Update 4.
"/maxilksize:2147483647",

# Force the creation of a .lib file for all executable() targets.
"/EXPORT:main",
]

# ASLR makes debugging with windbg difficult because Chrome.exe and
Expand Down
37 changes: 28 additions & 9 deletions build/toolchain/win/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ tool_wrapper_path = rebase_path("tool_wrapper.py", root_build_dir)

# Setup the Visual Studio state.
toolchain_data = exec_script("setup_toolchain.py",
[
visual_studio_path,
windows_sdk_path,
visual_studio_runtime_dirs,
current_cpu,
],
"scope")
[
visual_studio_path,
windows_sdk_path,
visual_studio_runtime_dirs,
current_cpu,
],
"scope")

if (vc_bin_dir == "") {
vc_bin_dir = toolchain_data.vc_bin_dir
Expand Down Expand Up @@ -164,6 +164,26 @@ template("msvc_toolchain") {
rspfile_content = "{{libs}} {{solibs}} {{inputs_newline}} {{ldflags}}"
}

tool("solink_module") {
dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}" # e.g. foo.dll
pdbname = "${dllname}.pdb"
rspfile = "${dllname}.rsp"

command = "$python_path $tool_wrapper_path link-wrapper $env False link.exe /nologo /DLL /OUT:$dllname /PDB:$pdbname @$rspfile"
default_output_extension = ".dll"
default_output_dir = "{{root_out_dir}}"
description = "LINK_MODULE(DLL) {{output}}"
outputs = [
dllname,
pdbname,
]
runtime_outputs = outputs

# The use of inputs_newline is to work around a fixed per-line buffer
# size in the linker.
rspfile_content = "{{libs}} {{solibs}} {{inputs_newline}} {{ldflags}}"
}

tool("link") {
binary_output =
"{{root_out_dir}}/{{target_output_name}}{{output_extension}}"
Expand Down Expand Up @@ -194,8 +214,7 @@ template("msvc_toolchain") {
}

tool("copy") {
command =
"$python_path $tool_wrapper_path recursive-mirror {{source}} {{output}}"
command = "$python_path $tool_wrapper_path recursive-mirror {{source}} {{output}}"
description = "COPY {{source}} {{output}}"
}

Expand Down
23 changes: 18 additions & 5 deletions runtime/bin/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,24 @@ template("dart_executable") {
deps += [ "//third_party/tcmalloc" ]
}

include_dirs = [
"..",
"//third_party",
]

if (dart_use_crashpad) {
assert(is_win, "dart_use_crashpad is only supported on Windows")
deps += [
"//third_party/crashpad/crashpad/client",
"//third_party/mini_chromium/mini_chromium/base",

# This binary is used to handle crashes of the dart binary.
"//third_party/crashpad/crashpad/handler:crashpad_handler",
]
include_dirs += [ "//third_party/crashpad" ]
defines += [ "DART_USE_CRASHPAD" ]
}

sources = [
"dart_embedder_api_impl.cc",
"error_exit.cc",
Expand All @@ -690,11 +708,6 @@ template("dart_executable") {
"vmservice_impl.h",
] + extra_sources

include_dirs = [
"..",
"//third_party",
]

if (is_win) {
ldflags = [ "/EXPORT:Dart_True" ]
} else {
Expand Down
10 changes: 10 additions & 0 deletions runtime/bin/filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,16 @@ ZLibDeflateFilter::~ZLibDeflateFilter() {

bool ZLibDeflateFilter::Init() {
int window_bits = window_bits_;
if ((raw_ || gzip_) && (window_bits == 8)) {
// zlib deflater does not work with windows size of 8 bits. Old versions
// of zlib would silently upgrade window size to 9 bits, newer versions
// return Z_STREAM_ERROR if window size is 8 bits but the stream header
// is suppressed. To maintain the old behavior upgrade window size here.
// This is safe because you can inflate a stream deflated with zlib
// using 9-bits with 8-bits window.
// For more details see https://crbug.com/691074.
window_bits = 9;
}
if (raw_) {
window_bits = -window_bits;
} else if (gzip_) {
Expand Down
49 changes: 49 additions & 0 deletions runtime/bin/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
#include "include/dart_embedder_api.h"
#include "include/dart_tools_api.h"

#if defined(DART_USE_CRASHPAD)
#include "crashpad/client/crashpad_client.h"
#include "crashpad/client/crashpad_info.h"
#endif

#include "bin/builtin.h"
#include "bin/console.h"
#include "bin/dartutils.h"
Expand Down Expand Up @@ -947,6 +952,45 @@ Dart_Handle GetVMServiceAssetsArchiveCallback() {
static Dart_GetVMServiceAssetsArchive GetVMServiceAssetsArchiveCallback = NULL;
#endif // !defined(NO_OBSERVATORY)

#if defined(DART_USE_CRASHPAD)
#if !defined(HOST_OS_WINDOWS)
#error "Currently we only support Crashpad on Windows"
#endif

static void ConfigureCrashpadClient(crashpad::CrashpadClient* client) {
// DART_CRASHPAD_HANDLER and DART_CRASHPAD_CRASHES_DIR are set by the
// testing framework.
wchar_t* handler = _wgetenv(L"DART_CRASHPAD_HANDLER");
wchar_t* crashes_dir = _wgetenv(L"DART_CRASHPAD_CRASHES_DIR");
if (handler == nullptr || crashes_dir == nullptr) {
return;
}

// Crashpad uses STL so we use it here too even though in general we
// avoid it.
const base::FilePath handler_path{std::wstring(handler)};
const base::FilePath crashes_dir_path{std::wstring(crashes_dir)};
const std::string url("");
std::map<std::string, std::string> annotations;
char* test_name = getenv("DART_TEST_NAME");
if (test_name != nullptr) {
annotations["dart_test_name"] = test_name;
}

std::vector<std::string> arguments;
if (!client->StartHandler(handler_path, crashes_dir_path, crashes_dir_path,
url, annotations, arguments,
/*restartable=*/true,
/*asynchronous_start=*/false)) {
Log::PrintErr("Failed to start the crash handler!\n");
Platform::Exit(kErrorExitCode);
}
crashpad::CrashpadInfo::GetCrashpadInfo()
->set_gather_indirectly_referenced_memory(crashpad::TriState::kEnabled,
/*limit=*/500 * MB);
}
#endif // DART_USE_CRASHPAD

void main(int argc, char** argv) {
char* script_name;
const int EXTRA_VM_ARGUMENTS = 10;
Expand Down Expand Up @@ -1010,6 +1054,11 @@ void main(int argc, char** argv) {
}
DartUtils::SetEnvironment(Options::environment());

#if defined(DART_USE_CRASHPAD)
crashpad::CrashpadClient crashpad_client;
ConfigureCrashpadClient(&crashpad_client);
#endif

Loader::InitOnce();

#if defined(DART_LINK_APP_SNAPSHOT)
Expand Down
54 changes: 0 additions & 54 deletions runtime/bin/zlib/BUILD.gn

This file was deleted.

9 changes: 5 additions & 4 deletions runtime/runtime_args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,17 @@ declare_args() {
# verified at the operating system level.
dart_use_fallback_root_certificates = false

# The BUILD.gn file that we pull from chromium as part of zlib has a
# dependence on //base, which we don't pull in. In a standalone build of the
# VM, we set this to //runtime/bin/zlib where we have a BUILD.gn file without
# a dependence on //base.
# TODO(vegorov): Can we eliminate this?
dart_zlib_path = "//third_party/zlib"

# Whether to link the standalone VM against tcmalloc. The standalone build of
# the VM enables this only for Linux builds.
dart_use_tcmalloc = false

# Whether to link Crashpad library for crash handling. Only supported on
# Windows for now.
dart_use_crashpad = false

# Controls the kind of core snapshot linked into the standalone VM. Using a
# core-jit snapshot breaks the ability to change various flags that affect
# code generation.
Expand Down
1 change: 1 addition & 0 deletions third_party/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
!clang.tar.gz.sha1
!unittest.tar.gz.sha1
!update.sh
!/googletest
18 changes: 15 additions & 3 deletions tools/gn.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
DART_USE_TSAN = "DART_USE_TSAN" # Use instead of --tsan
DART_USE_TOOLCHAIN = "DART_USE_TOOLCHAIN" # Use instread of --toolchain-prefix
DART_USE_SYSROOT = "DART_USE_SYSROOT" # Use instead of --target-sysroot
DART_USE_CRASHPAD = "DART_USE_CRASHPAD" # Use instead of --use-crashpad
# use instead of --platform-sdk
DART_MAKE_PLATFORM_SDK = "DART_MAKE_PLATFORM_SDK"

Expand Down Expand Up @@ -160,7 +161,6 @@ def UseSysroot(args, gn_args):
# Otherwise use the sysroot.
return True


def ToGnArgs(args, mode, arch, target_os):
gn_args = {}

Expand All @@ -174,6 +174,13 @@ def ToGnArgs(args, mode, arch, target_os):
gn_args['target_cpu'] = TargetCpuForArch(arch, target_os)
gn_args['dart_target_arch'] = DartTargetCpuForArch(arch)

# Configure Crashpad library if it is used.
gn_args['dart_use_crashpad'] = (args.use_crashpad or
DART_USE_CRASHPAD in os.environ)
if gn_args['dart_use_crashpad']:
# Tell Crashpad's BUILD files which checkout layout to use.
gn_args['crashpad_dependencies'] = 'dart'

if arch != HostCpuForArch(arch):
# Training an app-jit snapshot under a simulator is slow. Use script
# snapshots instead.
Expand All @@ -188,8 +195,6 @@ def ToGnArgs(args, mode, arch, target_os):

gn_args['dart_platform_bytecode'] = args.bytecode

gn_args['dart_zlib_path'] = "//runtime/bin/zlib"

# Use tcmalloc only when targeting Linux and when not using ASAN.
gn_args['dart_use_tcmalloc'] = ((gn_args['target_os'] == 'linux')
and not UseSanitizer(args))
Expand Down Expand Up @@ -321,6 +326,9 @@ def ProcessOptions(args):
print ("Cross-compilation to %s is not supported for architecture %s."
% (os_name, arch))
return False
if HOST_OS != 'win' and args.use_crashpad:
print "Crashpad is only supported on Windows"
return False
return True


Expand Down Expand Up @@ -460,6 +468,10 @@ def parse_args(args):
help='Number of simultaneous GN invocations',
dest='workers',
default=multiprocessing.cpu_count())
other_group.add_argument('--use-crashpad',
default=False,
dest='use_crashpad',
action='store_true')

options = parser.parse_args(args)
if not ProcessOptions(options):
Expand Down
Loading

0 comments on commit 2c83eb5

Please sign in to comment.