Browse Source

Add script to generate symbols from pdbs on Windows.

Cheng Zhao 11 years ago
parent
commit
ffaf535d00

+ 8 - 0
docs/development/build-instructions-windows.md

@@ -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.

+ 9 - 7
script/create-dist.py

@@ -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():

+ 4 - 3
tools/mac/generate_breakpad_symbols.py

@@ -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)

+ 127 - 0
tools/win/generate_breakpad_symbols.py

@@ -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())

+ 1 - 1
vendor/breakpad

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