Skip to content

Commit

Permalink
fix: dump correct breakpad symbols on macOS (#19157)
Browse files Browse the repository at this point in the history
  • Loading branch information
nornagon authored and zcbenz committed Jul 9, 2019
1 parent bff8573 commit a2f68c1
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 254 deletions.
16 changes: 1 addition & 15 deletions .circleci/config.yml
Expand Up @@ -402,25 +402,13 @@ step-mksnapshot-store: &step-mksnapshot-store
path: src/out/Default/mksnapshot.zip
destination: mksnapshot.zip

step-maybe-build-dump-syms: &step-maybe-build-dump-syms
run:
name: Build dump_syms binary
command: |
if [ "$GENERATE_SYMBOLS" == "true" ]; then
cd src
# Build needed dump_syms executable
ninja -C out/Default third_party/breakpad:dump_syms
fi
step-maybe-generate-breakpad-symbols: &step-maybe-generate-breakpad-symbols
run:
name: Generate breakpad symbols
command: |
if [ "$GENERATE_SYMBOLS" == "true" ]; then
cd src
export BUILD_PATH="$PWD/out/Default"
export DEST_PATH="$BUILD_PATH/breakpad_symbols"
electron/script/dump-symbols.py -b $BUILD_PATH -d $DEST_PATH -v
ninja -C out/Default electron:electron_symbols
fi
step-maybe-zip-symbols: &step-maybe-zip-symbols
Expand Down Expand Up @@ -629,7 +617,6 @@ steps-electron-build-for-tests: &steps-electron-build-for-tests
# Save all data needed for a further tests run.
- *step-persist-data-for-tests

- *step-maybe-build-dump-syms
- *step-maybe-generate-breakpad-symbols
- *step-maybe-zip-symbols

Expand All @@ -654,7 +641,6 @@ steps-electron-build-for-publish: &steps-electron-build-for-publish
- *step-maybe-electron-dist-strip
- *step-electron-dist-build
- *step-electron-dist-store
- *step-maybe-build-dump-syms
- *step-maybe-generate-breakpad-symbols
- *step-maybe-zip-symbols

Expand Down
116 changes: 115 additions & 1 deletion BUILD.gn
Expand Up @@ -9,6 +9,7 @@ import("//tools/grit/repack.gni")
import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
import("//v8/snapshot_toolchain.gni")
import("build/asar.gni")
import("build/extract_symbols.gni")
import("build/js_wrap.gni")
import("build/npm.gni")
import("buildflags/buildflags.gni")
Expand Down Expand Up @@ -536,6 +537,7 @@ if (is_mac) {
electron_helper_name = "$electron_product_name Helper"
electron_login_helper_name = "$electron_product_name Login Helper"
electron_framework_version = "A"
electron_version = read_file("ELECTRON_VERSION", "trim string")

mac_xib_bundle_data("electron_xibs") {
sources = [
Expand Down Expand Up @@ -618,7 +620,6 @@ if (is_mac) {
}
info_plist = "atom/common/resources/mac/Info.plist"

electron_version = read_file("ELECTRON_VERSION", "trim string")
extra_substitutions = [
"ATOM_BUNDLE_ID=$electron_mac_bundle_id.framework",
"ELECTRON_VERSION=$electron_version",
Expand Down Expand Up @@ -789,6 +790,76 @@ if (is_mac) {
"@executable_path/../Frameworks",
]
}

if (enable_dsyms) {
extract_symbols("electron_framework_syms") {
binary = "$root_out_dir/$electron_framework_name.framework/Versions/$electron_framework_version/$electron_framework_name"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/$electron_framework_name.dSYM/Contents/Resources/DWARF/$electron_framework_name"
deps = [
":electron_framework",
]
}

extract_symbols("electron_helper_syms") {
binary = "$root_out_dir/$electron_helper_name.app/Contents/MacOS/$electron_helper_name"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/$electron_helper_name.dSYM/Contents/Resources/DWARF/$electron_helper_name"
deps = [
":electron_helper_app",
]
}

extract_symbols("electron_app_syms") {
binary = "$root_out_dir/$electron_product_name.app/Contents/MacOS/$electron_product_name"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/$electron_product_name.dSYM/Contents/Resources/DWARF/$electron_product_name"
deps = [
":electron_app",
]
}

extract_symbols("swiftshader_egl_syms") {
binary = "$root_out_dir/libswiftshader_libEGL.dylib"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/libswiftshader_libEGL.dylib.dSYM/Contents/Resources/DWARF/libswiftshader_libEGL.dylib"
deps = [
"//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL",
]
}

extract_symbols("swiftshader_gles_syms") {
binary = "$root_out_dir/libswiftshader_libGLESv2.dylib"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/libswiftshader_libGLESv2.dylib.dSYM/Contents/Resources/DWARF/libswiftshader_libGLESv2.dylib"
deps = [
"//third_party/swiftshader/src/OpenGL/libGLESv2:swiftshader_libGLESv2",
]
}

extract_symbols("crashpad_handler_syms") {
binary = "$root_out_dir/crashpad_handler"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/crashpad_handler.dSYM/Contents/Resources/DWARF/crashpad_handler"
deps = [
"//third_party/crashpad/crashpad/handler:crashpad_handler",
]
}

group("electron_symbols") {
deps = [
":crashpad_handler_syms",
":electron_app_syms",
":electron_framework_syms",
":electron_helper_syms",
":swiftshader_egl_syms",
":swiftshader_gles_syms",
]
}
} else {
group("electron_symbols") {
}
}
} else {
windows_manifest("electron_app_manifest") {
sources = [
Expand Down Expand Up @@ -886,6 +957,49 @@ if (is_mac) {
}
}
}

if (is_official_build) {
if (is_linux) {
_target_executable_suffix = ""
_target_shared_library_suffix = ".so"
} else if (is_win) {
_target_executable_suffix = ".exe"
_target_shared_library_suffix = ".dll"
}

extract_symbols("electron_app_symbols") {
binary = "$root_out_dir/$electron_project_name$_target_executable_suffix"
symbol_dir = "$root_out_dir/breakpad_symbols"
deps = [
":electron_app",
]
}

extract_symbols("swiftshader_egl_symbols") {
binary = "$root_out_dir/swiftshader/libEGL$_target_shared_library_suffix"
symbol_dir = "$root_out_dir/breakpad_symbols"
deps = [
"//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL",
]
}

extract_symbols("swiftshader_gles_symbols") {
binary =
"$root_out_dir/swiftshader/libGLESv2$_target_shared_library_suffix"
symbol_dir = "$root_out_dir/breakpad_symbols"
deps = [
"//third_party/swiftshader/src/OpenGL/libGLESv2:swiftshader_libGLESv2",
]
}

group("electron_symbols") {
deps = [
":electron_app_symbols",
":swiftshader_egl_symbols",
":swiftshader_gles_symbols",
]
}
}
}

template("dist_zip") {
Expand Down
5 changes: 3 additions & 2 deletions appveyor.yml
Expand Up @@ -68,9 +68,10 @@ build_script:
- appveyor PushArtifact out/ffmpeg/ffmpeg.zip
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
ninja -C out/Default third_party/breakpad:dump_syms
# Needed for msdia140.dll on 64-bit windows
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
ninja -C out/Default electron:electron_symbols
}
- if "%GN_CONFIG%"=="release" ( python electron\script\dump-symbols.py -d %cd%\out\Default\breakpad_symbols -v)
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
python electron\script\zip-symbols.py
Expand Down
52 changes: 52 additions & 0 deletions build/dump_syms.py
@@ -0,0 +1,52 @@
from __future__ import print_function

import collections
import os
import subprocess
import sys
import errno

# The BINARY_INFO tuple describes a binary as dump_syms identifies it.
BINARY_INFO = collections.namedtuple('BINARY_INFO',
['platform', 'arch', 'hash', 'name'])

def get_module_info(header_info):
# header info is of the form "MODULE $PLATFORM $ARCH $HASH $BINARY"
info_split = header_info.strip().split(' ', 4)
if len(info_split) != 5 or info_split[0] != 'MODULE':
return None
return BINARY_INFO(*info_split[1:])

def get_symbol_path(symbol_data):
module_info = get_module_info(symbol_data[:symbol_data.index('\n')])
if not module_info:
raise Exception("Couldn't get module info for binary '{}'".format(binary))
return os.path.join(module_info.name, module_info.hash, module_info.name + ".sym")

def mkdir_p(path):
"""Simulates mkdir -p."""
try:
os.makedirs(path)
except OSError as e:
if e.errno == errno.EEXIST and os.path.isdir(path):
pass
else: raise

def main(dump_syms, binary, out_dir, stamp_file, dsym_file=None):
args = [dump_syms]
if dsym_file:
args += ["-g", dsym_file]
args += [binary]

symbol_data = subprocess.check_output(args)
symbol_path = os.path.join(out_dir, get_symbol_path(symbol_data))
mkdir_p(os.path.dirname(symbol_path))

with open(symbol_path, 'w') as out:
out.write(symbol_data)

with open(stamp_file, 'w'):
pass

if __name__ == '__main__':
main(*sys.argv[1:])
55 changes: 55 additions & 0 deletions build/extract_symbols.gni
@@ -0,0 +1,55 @@
import("//build/toolchain/toolchain.gni")

# Extracts symbols from a binary into a symbol file using dump_syms.
#
# Args:
# binary: Path to the binary containing symbols to extract, e.g.:
# "$root_out_dir/electron"
# symbol_dir: Desired output directory for symbols, e.g.:
# "$root_out_dir/breakpad_symbols"

if (host_os == "win") {
_host_executable_suffix = ".exe"
} else {
_host_executable_suffix = ""
}

template("extract_symbols") {
action(target_name) {
forward_variables_from(invoker,
[
"deps",
"testonly",
])
assert(defined(invoker.binary), "Need binary to dump")
assert(defined(invoker.symbol_dir), "Need directory for symbol output")

dump_syms_label = "//third_party/breakpad:dump_syms($host_toolchain)"
dump_syms_binary = get_label_info(dump_syms_label, "root_out_dir") +
"/dump_syms$_host_executable_suffix"

script = "//electron/build/dump_syms.py"
inputs = [
invoker.binary,
dump_syms_binary,
]
stamp_file = "${target_gen_dir}/${target_name}.stamp"
outputs = [
stamp_file,
]
args = [
"./" + rebase_path(dump_syms_binary, root_build_dir),
rebase_path(invoker.binary, root_build_dir),
rebase_path(invoker.symbol_dir, root_build_dir),
rebase_path(stamp_file, root_build_dir),
]
if (defined(invoker.dsym_file)) {
args += [ rebase_path(invoker.dsym_file, root_build_dir) ]
}

if (!defined(deps)) {
deps = []
}
deps += [ dump_syms_label ]
}
}

0 comments on commit a2f68c1

Please sign in to comment.