Bug 1361900: Part 3 - Add a helper script to decode and inspect script cache data. r?erahm draft
authorKris Maglione <maglione.k@gmail.com>
Sun, 30 Apr 2017 13:00:55 -0700
changeset 575178 05b18b96f0e2083d14aaa8ef570e80dcbb1c8b02
parent 575177 e54e84924097578d241dfc8a93f0953426f997cb
child 575179 a8258ded3156978b20eb4725fc6992c14366a9b1
child 577041 e3bd7cc4843a0a7758d5fe37321c89b90a465ed0
push id57985
push usermaglione.k@gmail.com
push dateWed, 10 May 2017 03:01:16 +0000
reviewerserahm
bugs1361900
milestone55.0a1
Bug 1361900: Part 3 - Add a helper script to decode and inspect script cache data. r?erahm MozReview-Commit-ID: DOj7X46NaZ5
js/xpconnect/loader/script_cache.py
new file mode 100755
--- /dev/null
+++ b/js/xpconnect/loader/script_cache.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+import io
+import os
+import struct
+import sys
+
+MAGIC = b'mozXDRcachev001\0'
+
+
+def usage():
+    print("""Usage: script_cache.py <file.bin> ...
+
+        Decodes and prints out the contents of a startup script cache file
+        (e.g., startupCache/scriptCache.bin) in human-readable form.""")
+
+    sys.exit(1)
+
+
+class ProcessTypes:
+    Default = 0
+    Web = 1
+    Extension = 2
+
+    def __init__(self, val):
+        self.val = val
+
+    def __str__(self):
+        res = []
+        if self.val & (1 << self.Default):
+            res.append('Parent')
+        if self.val & (1 << self.Web):
+            res.append('Web')
+        if self.val & (1 << self.Extension):
+            res.append('Extension')
+        return '|'.join(res)
+
+
+class InputBuffer(object):
+
+    def __init__(self, data):
+        self.data = data
+        self.offset = 0
+
+    @property
+    def remaining(self):
+        return len(self.data) - self.offset
+
+    def unpack(self, fmt):
+        res = struct.unpack_from(fmt, self.data, self.offset)
+        self.offset += struct.calcsize(fmt)
+        return res
+
+    def unpack_str(self):
+        size, = self.unpack('<H')
+        res = self.data[self.offset:self.offset + size].decode('utf-8')
+        self.offset += size
+        return res
+
+
+if len(sys.argv) < 2 or not os.path.exists(sys.argv[1]):
+    usage()
+
+for filename in sys.argv[1:]:
+    with io.open(filename, 'rb') as f:
+        magic = f.read(len(MAGIC))
+        if magic != MAGIC:
+            raise Exception('Bad magic number')
+
+        hdrSize, = struct.unpack('<I', f.read(4))
+
+        hdr = InputBuffer(f.read(hdrSize))
+
+        i = 0
+        while hdr.remaining:
+            i += 1
+            print('{}: {}'.format(i, hdr.unpack_str()))
+            print('  Key:       {}'.format(hdr.unpack_str()))
+            print('  Offset:    {:>9,}'.format(*hdr.unpack('<I')))
+            print('  Size:      {:>9,}'.format(*hdr.unpack('<I')))
+            print('  Processes: {}'.format(ProcessTypes(*hdr.unpack('B'))))
+            print('')