Add script to generate symbols from pdbs on Windows.

This commit is contained in:
Cheng Zhao 2013-11-26 21:23:50 +08:00
parent edf7496443
commit ffaf535d00
5 changed files with 149 additions and 11 deletions

View file

@ -18,6 +18,14 @@ softwares:
* [Windows 7 SDK](http://www.microsoft.com/en-us/download/details.aspx?id=8279)
* `Windows Headers` and `Visual C++ Compilers` are required.
If you want to dump breakpad symbols you also need to do this (you are free to
skip this step if you don't know what it is):
1. Get a copy of `msdia80.dll` and put it in
`C:\Program Files\Common Files\Microsoft Shared\VC\`.
2. As Administrator, run:
`regsvr32 c:\Program Files\Common Files\Microsoft Shared\VC\msdia80.dll`.
The instructions bellow are executed under [cygwin](http://www.cygwin.com),
but it's not a requirement, you can also build atom-shell under Windows's
console or other terminals.

View file

@ -152,20 +152,22 @@ def download_libchromiumcontent_symbols(url):
if sys.platform == 'darwin':
symbols_name = 'libchromiumcontent.dylib.dSYM'
else:
symbols_name = 'libchromiumcontent.dll.pdb'
symbols_path = os.path.join(OUT_DIR, symbols_name)
if os.path.exists(symbols_path):
return
symbols_name = 'chromiumcontent.dll.pdb'
brightray_dir = os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor')
target_dir = os.path.join(brightray_dir, 'download', 'libchromiumcontent')
symbols_path = os.path.join(target_dir, 'Release', symbols_name)
if os.path.exists(symbols_path):
return
download = os.path.join(brightray_dir, 'libchromiumcontent', 'script',
'download')
subprocess.check_call([sys.executable, download, '-f', '-s', url, target_dir])
shutil.copytree(os.path.join(target_dir, 'Release', symbols_name),
symbols_path,
symlinks=True)
if sys.platform == 'darwin':
shutil.copytree(symbols_path,
os.path.join(OUT_DIR, symbols_name),
symlinks=True)
def create_symbols():

View file

@ -1,5 +1,6 @@
#!/usr/bin/env python
# Copyright 2013 The Chromium Authors. All rights reserved.
# Copyright (c) 2013 GitHub, Inc. All rights reserved.
# Copyright (c) 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@ -171,8 +172,8 @@ def GenerateSymbols(options, binaries):
binary = queue.get()
if options.verbose:
with print_lock:
print "Generating symbols for %s" % binary
with print_lock:
print "Generating symbols for %s" % binary
if sys.platform == 'darwin':
binary = GetDSYMBundle(options.build_dir, binary)

View file

@ -0,0 +1,127 @@
#!/usr/bin/env python
# Copyright (c) 2013 GitHub, Inc. All rights reserved.
# Copyright (c) 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Convert pdb to sym for given directories"""
import errno
import glob
import optparse
import os
import Queue
import re
import subprocess
import sys
import threading
CONCURRENT_TASKS=4
SOURCE_ROOT=os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
DUMP_SYMS=os.path.join(SOURCE_ROOT, 'vendor', 'breakpad', 'dump_syms.exe')
def GetCommandOutput(command):
"""Runs the command list, returning its output.
Prints the given command (which should be a list of one or more strings),
then runs it and returns its output (stdout) as a string.
From chromium_utils.
"""
devnull = open(os.devnull, 'w')
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=devnull,
bufsize=1)
output = proc.communicate()[0]
return output
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 GenerateSymbols(options, binaries):
"""Dumps the symbols of binary and places them in the given directory."""
queue = Queue.Queue()
print_lock = threading.Lock()
def _Worker():
while True:
binary = queue.get()
if options.verbose:
with print_lock:
print "Generating symbols for %s" % binary
syms = GetCommandOutput([DUMP_SYMS, binary])
module_line = re.match("MODULE [^ ]+ [^ ]+ ([0-9A-F]+) (.*)\r\n", syms)
if module_line == None:
with print_lock:
print "Failed to get symbols for %s" % binary
queue.task_done()
continue
output_path = os.path.join(options.symbols_dir, module_line.group(2),
module_line.group(1))
mkdir_p(output_path)
symbol_file = "%s.sym" % module_line.group(2)
f = open(os.path.join(output_path, symbol_file), 'w')
f.write(syms)
f.close()
queue.task_done()
for binary in binaries:
queue.put(binary)
for _ in range(options.jobs):
t = threading.Thread(target=_Worker)
t.daemon = True
t.start()
queue.join()
def main():
parser = optparse.OptionParser()
parser.add_option('', '--symbols-dir', default='',
help='The directory where to write the symbols file.')
parser.add_option('', '--clear', default=False, action='store_true',
help='Clear the symbols directory before writing new '
'symbols.')
parser.add_option('-j', '--jobs', default=CONCURRENT_TASKS, action='store',
type='int', help='Number of parallel tasks to run.')
parser.add_option('-v', '--verbose', action='store_true',
help='Print verbose status output.')
(options, directories) = parser.parse_args()
if not options.symbols_dir:
print "Required option --symbols-dir missing."
return 1
if options.clear:
try:
shutil.rmtree(options.symbols_dir)
except:
pass
pdbs = []
for directory in directories:
pdbs += glob.glob(os.path.join(directory, '*.pdb'))
GenerateSymbols(options, pdbs)
return 0
if '__main__' == __name__:
sys.exit(main())

2
vendor/breakpad vendored

@ -1 +1 @@
Subproject commit 50cc121b00cc82b55dda8c51df54276b89f265d5
Subproject commit 2483f32da1f729ac362fbbcaa9173843379697e9