"""find_subclasses.py Find vtables that look like subclasses of a parent class (share parent's slot 1 = CopyInto address, indicating inheritance not overridden). For each such vtable, report slot 2 — if it equals noop_addr, the subclass inherits the no-op stub (= leak source). Used to find GraphicsResource subclasses that inherit the no-op PurgeResource and therefore leak forever. """ import struct, sys from minidump.minidumpfile import MinidumpFile def _ei(v): if v is None: return 0 if hasattr(v, 'value'): return int(v.value) return int(v) def main(): md = MinidumpFile.parse(sys.argv[1]) parent_vtable = int(sys.argv[2], 0) noop_addr = int(sys.argv[3], 0) reader = md.get_reader().get_buffered_reader() # Read parent's slot 1 - that's the "shared" value to look for reader.move(parent_vtable + 4) parent_slot1 = struct.unpack(" 0x10000000: continue # Skip parent itself if base + off == parent_vtable: continue found.append((base + off, slot0, slot2, slot3)) print(f"candidate subclass vtables: {len(found)}") print() print(f"{'vtable':<12} {'slot0 dtor':<12} {'slot2 Purge':<12} {'slot3 Restore':<12} inherits_noop?") for vt, s0, s2, s3 in found: marker = "*** LEAKS — inherits no-op PurgeResource ***" if s2 == noop_addr else "" print(f"0x{vt:08x} 0x{s0:08x} 0x{s2:08x} 0x{s3:08x} {marker}") if __name__ == "__main__": main()