Modified: trunk/Tools/ChangeLog (242824 => 242825)
--- trunk/Tools/ChangeLog 2019-03-12 20:40:51 UTC (rev 242824)
+++ trunk/Tools/ChangeLog 2019-03-12 20:55:49 UTC (rev 242825)
@@ -1,3 +1,22 @@
+2019-03-12 Robin Morisset <[email protected]>
+
+ Alter Tools/Scripts/dump-class-layout to be able to dump all classes with suspicious padding
+ https://bugs.webkit.org/show_bug.cgi?id=195573
+
+ Reviewed by Simon Fraser.
+
+ Also modified the script so that when multiple types match a given name it shows them all and not arbitrarily pick one.
+
+ * Scripts/dump-class-layout:
+ (main):
+ * lldb/lldb_dump_class_layout.py:
+ (ClassLayout.__init__):
+ (ClassLayout._compute_padding_recursive):
+ (LLDBDebuggerInstance.dump_layout_for_classname):
+ (LLDBDebuggerInstance):
+ (LLDBDebuggerInstance.dump_all_wasteful_layouts):
+ (LLDBDebuggerInstance.layout_for_classname): Deleted.
+
2019-03-12 Chris Dumez <[email protected]>
Device Orientation access permission should be denied unless explicitly granted by the client
Modified: trunk/Tools/Scripts/dump-class-layout (242824 => 242825)
--- trunk/Tools/Scripts/dump-class-layout 2019-03-12 20:40:51 UTC (rev 242824)
+++ trunk/Tools/Scripts/dump-class-layout 2019-03-12 20:55:49 UTC (rev 242825)
@@ -51,7 +51,7 @@
parser = argparse.ArgumentParser(description='Dumps the in-memory layout of the given class or classes, showing padding holes.')
parser.add_argument('framework', metavar='framework',
help='name of the framework containing the class (e.g. "WebCore")')
- parser.add_argument('classname', metavar='classname',
+ parser.add_argument('classname', metavar='classname', nargs='?',
help='name of the class or struct to dump')
parser.add_argument('-b', '--build-directory', dest='build_directory', action='',
@@ -66,6 +66,9 @@
parser.add_argument('-t', '--target-path', dest='target_path', action='',
help='Path to the target')
+ parser.add_argument('-w', '--all-wasteful', dest='all_wasteful', action='',
+ help='Exclusive with classname, dumps the layout of all classes with at least 8 bytes of padding at the top-level')
+
args = parser.parse_args()
build_dir = webkit_build_dir()
@@ -81,9 +84,14 @@
target_path = os.path.join(build_dir, args.config, args.framework + ".framework", args.framework);
lldb_instance = LLDBDebuggerInstance(target_path, args.arch)
- class_layout = lldb_instance.layout_for_classname(args.classname)
- class_layout.dump()
+ if args.all_wasteful and (args.classname is not None):
+ print "The -w/--all-wasteful option is incompatible with providing a class name"
+ elif args.all_wasteful:
+ lldb_instance.dump_all_wasteful_layouts()
+ elif args.classname is not None:
+ lldb_instance.dump_layout_for_classname(args.classname)
+ else:
+ print "You must either provide a class name or the -w/--all-wasteful option"
-
if __name__ == "__main__":
main()
Modified: trunk/Tools/lldb/lldb_dump_class_layout.py (242824 => 242825)
--- trunk/Tools/lldb/lldb_dump_class_layout.py 2019-03-12 20:40:51 UTC (rev 242824)
+++ trunk/Tools/lldb/lldb_dump_class_layout.py 2019-03-12 20:55:49 UTC (rev 242825)
@@ -145,6 +145,7 @@
self.total_byte_size = self.type.GetByteSize()
self.pointer_size = self.target.GetAddressByteSize()
self.total_pad_bytes = 0
+ self.top_level_pad_bytes = 0
self.data_members = []
self.virtual_base_classes = self._virtual_base_classes_dictionary()
self._parse(containerClass, derivedClass)
@@ -319,6 +320,8 @@
self.data_members.insert(i, padding_member)
padding_bytes += padding_size
+ if depth == 0 and padding_size < 8:
+ self.top_level_pad_bytes += padding_size
i += 1
if self.MEMBER_IS_BITFIELD in data_member:
@@ -364,6 +367,7 @@
}
self.data_members.append(padding_member)
padding_bytes += padding_size
+ self.top_level_pad_bytes += padding_size
return [padding_bytes, current_offset]
@@ -411,11 +415,22 @@
return lldb.LLDB_ARCH_DEFAULT
- def layout_for_classname(self, classname):
+ def dump_layout_for_classname(self, classname):
types = self.module.FindTypes(classname)
- if types.GetSize():
- # There can be more that one type with a given name, but for now just return the first one.
- return ClassLayout(self.target, types.GetTypeAtIndex(0))
+ if not types.GetSize():
+ print 'error: no type matches "%s" in "%s"' % (classname, self.module.file)
+ return None
+ for t in types:
+ ClassLayout(self.target, t).dump()
- print 'error: no type matches "%s" in "%s"' % (classname, self.module.file)
- return None
+ def dump_all_wasteful_layouts(self):
+ types = self.module.GetTypes(lldb.eTypeClassClass | lldb.eTypeClassStruct)
+ seenTypes = set()
+ for t in types:
+ if t.GetName() in seenTypes:
+ continue
+ seenTypes.add(t.GetName())
+ classLayout = ClassLayout(self.target, t)
+ if classLayout.top_level_pad_bytes >= 8:
+ classLayout.dump()
+ print ""