Bug 452866 - "Teach Socorro/crash-stats about comm-central - add support for multiple source directories to buildsymbols." [r=ted.mielczarek]
authorPhilippe M. Chiasson <gozer@mozillamessaging.com>
Tue, 17 Feb 2009 07:46:32 +0000
changeset 25054 d2d0110cd69aee5da2404c021380b7c9652500b9
parent 25053 9d0abe25b1622302533b8322ea481d2e9b2a942c
child 25055 e51cf7cb4f6397120e5f11c8e8ed3340607ca3e5
push id5380
push userbugzilla@standard8.plus.com
push dateTue, 17 Feb 2009 07:48:21 +0000
treeherdermozilla-central@d2d0110cd69a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs452866
milestone1.9.2a1pre
Bug 452866 - "Teach Socorro/crash-stats about comm-central - add support for multiple source directories to buildsymbols." [r=ted.mielczarek]
Makefile.in
toolkit/crashreporter/tools/symbolstore.py
--- a/Makefile.in
+++ b/Makefile.in
@@ -171,31 +171,35 @@ endif
 DUMP_SYMS_BIN ?= $(DIST)/host/bin/dump_syms
 endif
 ifeq (,$(filter-out Linux SunOS,$(OS_ARCH)))
 MAKE_SYM_STORE_ARGS := --vcs-info
 DUMP_SYMS_BIN ?= $(DIST)/host/bin/dump_syms
 MAKE_SYM_STORE_PATH := $(DIST)/bin
 endif
 
+SYM_STORE_SOURCE_DIRS := $(topsrcdir)
+
 ifdef MOZ_SYMBOLS_EXTRA_BUILDID
 EXTRA_BUILDID := -$(MOZ_SYMBOLS_EXTRA_BUILDID)
 endif
 
 SYMBOL_ARCHIVE_BASENAME = \
   $(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_ARCH)-$(BUILDID)$(EXTRA_BUILDID)
 
 buildsymbols:
 ifdef MOZ_CRASHREPORTER
 	echo building symbol store
 	mkdir -p $(DIST)/crashreporter-symbols/$(BUILDID)
-	$(PYTHON) $(topsrcdir)/toolkit/crashreporter/tools/symbolstore.py    \
-	  $(MAKE_SYM_STORE_ARGS) -s $(topsrcdir) $(DUMP_SYMS_BIN)     \
-	  $(DIST)/crashreporter-symbols/$(BUILDID)                    \
-	  $(MAKE_SYM_STORE_PATH) >                                    \
+	$(PYTHON) $(topsrcdir)/toolkit/crashreporter/tools/symbolstore.py \
+	  $(MAKE_SYM_STORE_ARGS)                                          \
+	  $(foreach dir,$(SYM_STORE_SOURCE_DIRS),-s $(dir))               \
+	  $(DUMP_SYMS_BIN)                                                \
+	  $(DIST)/crashreporter-symbols/$(BUILDID)                        \
+	  $(MAKE_SYM_STORE_PATH) >                                        \
 	  $(DIST)/crashreporter-symbols/$(BUILDID)/$(SYMBOL_ARCHIVE_BASENAME)-symbols.txt
 	echo packing symbols
 	mkdir -p $(topsrcdir)/../$(BUILDID)
 	cd $(DIST)/crashreporter-symbols/$(BUILDID) && \
           zip -r9D ../crashreporter-symbols-$(SYMBOL_ARCHIVE_BASENAME).zip .
 	mv $(DIST)/crashreporter-symbols/crashreporter-symbols-$(SYMBOL_ARCHIVE_BASENAME).zip \
           $(topsrcdir)/../$(BUILDID)
 endif # MOZ_CRASHREPORTER
--- a/toolkit/crashreporter/tools/symbolstore.py
+++ b/toolkit/crashreporter/tools/symbolstore.py
@@ -254,17 +254,17 @@ class SVNFileInfo(VCSFileInfo):
         if self.root and self.revision:
             if "URL" in self.svndata and "Repository Root" in self.svndata:
                 url, repo = self.svndata["URL"], self.svndata["Repository Root"]
                 file = url[len(repo) + 1:]
             return "svn:%s:%s:%s" % (self.root, file, self.revision)
         print >> sys.stderr, "Failed to get SVN Filename for %s" % self.file
         return self.file
 
-class HGRepoInfo():
+class HGRepoInfo:
     # HG info is per-repo, so cache it in a static
     # member var
     repos = {}
     def __init__(self, path, rev, cleanroot):
         self.path = path
         self.rev = rev
         self.cleanroot = cleanroot
 
@@ -325,17 +325,17 @@ class HGFileInfo(VCSFileInfo):
 vcsFileInfoCache = {}
 
 def IsInDir(file, dir):
     # the lower() is to handle win32+vc8, where
     # the source filenames come out all lowercase,
     # but the srcdir can be mixed case
     return os.path.abspath(file).lower().startswith(os.path.abspath(dir).lower())
 
-def GetVCSFilename(file, srcdir):
+def GetVCSFilename(file, srcdirs):
     """Given a full path to a file, and the top source directory,
     look for version control information about this file, and return
     a tuple containing
     1) a specially formatted filename that contains the VCS type,
     VCS location, relative filename, and revision number, formatted like:
     vcs:vcs location:filename:revision
     For example:
     cvs:cvs.mozilla.org/cvsroot:mozilla/browser/app/nsBrowserApp.cpp:1.36
@@ -345,25 +345,31 @@ def GetVCSFilename(file, srcdir):
         return (file, None)
 
     fileInfo = None
     root = ''
     if file in vcsFileInfoCache:
         # Already cached this info, use it.
         fileInfo = vcsFileInfoCache[file]
     else:
-        if os.path.isdir(os.path.join(path, "CVS")):
-            fileInfo = CVSFileInfo(file, srcdir)
-        elif os.path.isdir(os.path.join(path, ".svn")) or \
-             os.path.isdir(os.path.join(path, "_svn")):
-            fileInfo = SVNFileInfo(file);
-        elif os.path.isdir(os.path.join(srcdir, '.hg')) and \
-             IsInDir(file, srcdir):
-            fileInfo = HGFileInfo(file, srcdir)
-        vcsFileInfoCache[file] = fileInfo
+        for srcdir in srcdirs:
+            if os.path.isdir(os.path.join(path, "CVS")):
+                fileInfo = CVSFileInfo(file, srcdir)
+                if fileInfo:
+                    root = fileInfo.root
+            elif os.path.isdir(os.path.join(path, ".svn")) or \
+                 os.path.isdir(os.path.join(path, "_svn")):
+                 fileInfo = SVNFileInfo(file);
+            elif os.path.isdir(os.path.join(srcdir, '.hg')) and \
+                 IsInDir(file, srcdir):
+                 fileInfo = HGFileInfo(file, srcdir)
+
+            if fileInfo: 
+                vcsFileInfoCache[file] = fileInfo
+                break
 
     if fileInfo:
         file = fileInfo.filename
         root = fileInfo.root
 
     # we want forward slashes on win32 paths
     return (file.replace("\\", "/"), root)
 
@@ -401,29 +407,29 @@ class Dumper:
     and an option to copy debug info files alongside the dumped
     symbol files--|copy_debug|, mostly useful for creating a
     Microsoft Symbol Server from the resulting output.
 
     You don't want to use this directly if you intend to call
     ProcessDir.  Instead, call GetPlatformSpecificDumper to
     get an instance of a subclass."""
     def __init__(self, dump_syms, symbol_path,
-                 archs=None, srcdir=None, copy_debug=False, vcsinfo=False, srcsrv=False):
+                 archs=None, srcdirs=None, copy_debug=False, vcsinfo=False, srcsrv=False):
         # popen likes absolute paths, at least on windows
         self.dump_syms = os.path.abspath(dump_syms)
         self.symbol_path = symbol_path
         if archs is None:
             # makes the loop logic simpler
             self.archs = ['']
         else:
             self.archs = ['-a %s' % a for a in archs.split()]
-        if srcdir is not None:
-            self.srcdir = os.path.normpath(srcdir)
+        if srcdirs is not None:
+            self.srcdirs = [os.path.normpath(a) for a in srcdirs]
         else:
-            self.srcdir = None
+            self.srcdirs = None
         self.copy_debug = copy_debug
         self.vcsinfo = vcsinfo
         self.srcsrv = srcsrv
 
     # subclasses override this
     def ShouldProcess(self, file):
         return False
 
@@ -506,24 +512,25 @@ class Dumper:
                     f = open(full_path, "w")
                     f.write(module_line)
                     # now process the rest of the output
                     for line in cmd:
                         if line.startswith("FILE"):
                             # FILE index filename
                             (x, index, filename) = line.split(None, 2)
                             if sys.platform == "sunos5":
-                                start = filename.find(self.srcdir)
-                                if start == -1:
-                                    start = 0
-                                filename = filename[start:]
+                                for srcdir in self.srcdirs:
+                                    start = filename.find(self.srcdir)
+                                    if start != -1:
+                                        filename = filename[start:]
+                                        break
                             filename = self.FixFilenameCase(filename.rstrip())
                             sourcepath = filename
                             if self.vcsinfo:
-                                (filename, rootname) = GetVCSFilename(filename, self.srcdir)
+                                (filename, rootname) = GetVCSFilename(filename, self.srcdirs)
                                 # sets vcs_root in case the loop through files were to end on an empty rootname
                                 if vcs_root is None:
                                   if rootname:
                                      vcs_root = rootname
                             # gather up files with hg for indexing   
                             if filename.startswith("hg"):
                                 (ver, checkout, source_file, revision) = filename.split(":", 3)
                                 sourceFileStream += sourcepath + "*" + source_file + '*' + revision + "\r\n"
@@ -710,17 +717,17 @@ def main():
     parser = OptionParser(usage="usage: %prog [options] <dump_syms binary> <symbol store path> <debug info files>")
     parser.add_option("-c", "--copy",
                       action="store_true", dest="copy_debug", default=False,
                       help="Copy debug info files into the same directory structure as symbol files")
     parser.add_option("-a", "--archs",
                       action="store", dest="archs",
                       help="Run dump_syms -a <arch> for each space separated cpu architecture in ARCHS (only on OS X)")
     parser.add_option("-s", "--srcdir",
-                      action="store", dest="srcdir",
+                      action="append", dest="srcdir", default=[],
                       help="Use SRCDIR to determine relative paths to source files")
     parser.add_option("-v", "--vcs-info",
                       action="store_true", dest="vcsinfo",
                       help="Try to retrieve VCS info for each FILE listed in the output")
     parser.add_option("-i", "--source-index",
                       action="store_true", dest="srcsrv", default=False,
                       help="Add source index information to debug files, making them suitable for use in a source server.")
     (options, args) = parser.parse_args()
@@ -735,17 +742,17 @@ def main():
     if len(args) < 3:
         parser.error("not enough arguments")
         exit(1)
 
     dumper = GetPlatformSpecificDumper(dump_syms=args[0],
                                        symbol_path=args[1],
                                        copy_debug=options.copy_debug,
                                        archs=options.archs,
-                                       srcdir=options.srcdir,
+                                       srcdirs=options.srcdir,
                                        vcsinfo=options.vcsinfo,
                                        srcsrv=options.srcsrv)
     for arg in args[2:]:
         dumper.Process(arg)
 
 # run main if run directly
 if __name__ == "__main__":
     main()