import gdb, sys inf = gdb.selected_inferior() pid = inf.pid base = None for line in open("/proc/%d/maps" % pid): if "libnvidia-eglcore.so.570.144" in line: parts = line.split() lo, hi = [int(x, 16) for x in parts[0].split('-')] off = int(parts[2], 16) if off == 0: base = lo break if base is None: print("EGLBASE not found"); gdb.execute("detach"); sys.exit(1) COUNT = base + 0x2070b7c print("EGLBASE 0x%x PID %d COUNT 0x%x" % (base, pid, COUNT)) def rd(a, n): return inf.read_memory(a, n).tobytes() def u32(a): return int.from_bytes(rd(a, 4), 'little') def u64(a): return int.from_bytes(rd(a, 8), 'little') state = {"clears": 0, "mp": 0, "am": 0} class B(gdb.Breakpoint): def __init__(self, spec, fn, limit=100000): super().__init__(spec, internal=False) self.fn = fn; self.limit = limit; self.hits = 0 self.silent = True def stop(self): self.hits += 1 try: stop = bool(self.fn(self)) except Exception as e: print("ERR@0x%x %s" % (int(gdb.parse_and_eval("$pc")), e)) stop = False return stop or self.hits >= self.limit def clear(bp): try: v = u32(COUNT) if v: state["clears"] += 1 if state["clears"] <= 5: print("CLEAR count %u -> 0" % v) gdb.execute("set {unsigned int}0x%x = 0" % COUNT) except Exception as e: print("CLEAR err", e) return False def mp(bp): rsi = int(gdb.parse_and_eval("$rsi")) state["mp"] += 1 if state["mp"] <= 3: print("MEMPROPS ptr=0x%x" % rsi) return False def am(bp): rsi = int(gdb.parse_and_eval("$rsi")) state["am"] += 1 if state["am"] <= 10: try: st = u32(rsi) size = u64(rsi+0x10) tidx = u32(rsi+0x18) print("ALLOC sType=%d size=0x%x typeIndex=%d" % (st, size, tidx)) except Exception as e: print("ALLOC err", e) return False B("*0x%x" % (base+0xa85d24), clear, 100000) try: B("vkGetPhysicalDeviceMemoryProperties", mp, 5) except Exception as e: print("MP BP err", e) try: B("vkAllocateMemory", am, 20) except Exception as e: print("AM BP err", e) try: gdb.execute("continue") except gdb.error as e: print("CONT-ERR %s" % e) except KeyboardInterrupt: pass print("TRACE-END clears=%d" % state["clears"]) try: gdb.execute("detach") except gdb.error as e: print("DETACH-ERR %s" % e) gdb.execute("quit")