bug 1156300 - symbolstore.py FixFilenameCase doesn't fix up directory names. r=gps
authorTed Mielczarek <ted@mielczarek.org>
Mon, 11 Apr 2016 08:53:42 -0400
changeset 330496 7fb9838b488ae278f5b22132be5398cd41a9ce57
parent 330495 890bb7f1858f6be0563b7eea5d8e616689ad03dd
child 330497 563d9fd3012dcb274825be2ced757ece8790f842
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps
bugs1156300
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1156300 - symbolstore.py FixFilenameCase doesn't fix up directory names. r=gps MozReview-Commit-ID: 2nEaouS1oHD
toolkit/crashreporter/tools/symbolstore.py
toolkit/crashreporter/tools/unit-symbolstore.py
--- a/toolkit/crashreporter/tools/symbolstore.py
+++ b/toolkit/crashreporter/tools/symbolstore.py
@@ -744,23 +744,42 @@ class Dumper_Win32(Dumper):
 
         # Use a cached version if we have one.
         if file in self.fixedFilenameCaseCache:
             return self.fixedFilenameCaseCache[file]
 
         result = file
 
         ctypes.windll.kernel32.SetErrorMode(ctypes.c_uint(1))
-        (path, filename) = os.path.split(file)
-        if os.path.isdir(path):
-            lc_filename = filename.lower()
-            for f in os.listdir(path):
-                if f.lower() == lc_filename:
-                    result = os.path.join(path, f)
-                    break
+        if not isinstance(file, unicode):
+            file = unicode(file, sys.getfilesystemencoding())
+        handle = ctypes.windll.kernel32.CreateFileW(file,
+                                                    # GENERIC_READ
+                                                    0x80000000,
+                                                    # FILE_SHARE_READ
+                                                    1,
+                                                    None,
+                                                    # OPEN_EXISTING
+                                                    3,
+                                                    0,
+                                                    None)
+        if handle != -1:
+            size = ctypes.windll.kernel32.GetFinalPathNameByHandleW(handle,
+                                                                    None,
+                                                                    0,
+                                                                    0)
+            buf = ctypes.create_unicode_buffer(size)
+            if ctypes.windll.kernel32.GetFinalPathNameByHandleW(handle,
+                                                                buf,
+                                                                size,
+                                                                0) > 0:
+                # The return value of GetFinalPathNameByHandleW uses the
+                # '\\?\' prefix.
+                result = buf.value.encode(sys.getfilesystemencoding())[4:]
+            ctypes.windll.kernel32.CloseHandle(handle)
 
         # Cache the corrected version to avoid future filesystem hits.
         self.fixedFilenameCaseCache[file] = result
         return result
 
     def CopyDebug(self, file, debug_file, guid, code_file, code_id):
         def compress(path):
             compressed_file = path[:-1] + '_'
--- a/toolkit/crashreporter/tools/unit-symbolstore.py
+++ b/toolkit/crashreporter/tools/unit-symbolstore.py
@@ -59,22 +59,25 @@ class HelperMixin(object):
         symbolstore.srcdirRepoInfo = {}
         symbolstore.vcsFileInfoCache = {}
 
     def tearDown(self):
         shutil.rmtree(self.test_dir)
         symbolstore.srcdirRepoInfo = {}
         symbolstore.vcsFileInfoCache = {}
 
+    def make_dirs(self, f):
+        d = os.path.dirname(f)
+        if d and not os.path.exists(d):
+            os.makedirs(d)
+
     def add_test_files(self, files):
         for f in files:
             f = os.path.join(self.test_dir, f)
-            d = os.path.dirname(f)
-            if d and not os.path.exists(d):
-                os.makedirs(d)
+            self.make_dirs(f)
             writer(f)
 
 class TestSizeOrder(HelperMixin, unittest.TestCase):
     def test_size_order(self):
         """
         Test that files are processed ordered by size on disk.
         """
         processed = []
@@ -283,16 +286,41 @@ class TestRepoManifest(HelperMixin, unit
         self.assertEqual("git:example.com/bar/projects/one:src1.c:abcd1234",
                          symbolstore.GetVCSFilename(file1, d.srcdirs)[0])
         self.assertEqual("git:example.com/foo/projects/two:src2.c:ffffffff",
                          symbolstore.GetVCSFilename(file2, d.srcdirs)[0])
         self.assertEqual("git:example.com/bar/something_else:src3.c:00000000",
                          symbolstore.GetVCSFilename(file3, d.srcdirs)[0])
 
 if platform.system() in ("Windows", "Microsoft"):
+    class TestFixFilenameCase(HelperMixin, unittest.TestCase):
+        def test_fix_filename_case(self):
+            # self.test_dir is going to be 8.3 paths...
+            junk = os.path.join(self.test_dir, 'x')
+            with open(junk, 'wb') as o:
+                o.write('x')
+            d = symbolstore.Dumper_Win32(dump_syms='dump_syms',
+                                         symbol_path=self.test_dir)
+            fixed_dir = os.path.dirname(d.FixFilenameCase(junk))
+            files = [
+                'one\\two.c',
+                'three\\Four.d',
+                'Five\\Six.e',
+                'seven\\Eight\\nine.F',
+            ]
+            for rel_path in files:
+                full_path = os.path.normpath(os.path.join(self.test_dir,
+                                                          rel_path))
+                self.make_dirs(full_path)
+                with open(full_path, 'wb') as o:
+                    o.write('x')
+                fixed_path = d.FixFilenameCase(full_path.lower())
+                fixed_path = os.path.relpath(fixed_path, fixed_dir)
+                self.assertEqual(rel_path, fixed_path)
+
     class TestSourceServer(HelperMixin, unittest.TestCase):
         @patch("subprocess.call")
         @patch("subprocess.Popen")
         def test_HGSERVER(self, mock_Popen, mock_call):
             """
             Test that HGSERVER gets set correctly in the source server index.
             """
             symbolpath = os.path.join(self.test_dir, "symbols")