52 lines
1.4 KiB
Python
52 lines
1.4 KiB
Python
import gdb
|
|
|
|
def jitmap_raw():
|
|
pid = gdb.selected_inferior().pid
|
|
jitmap_file = open("/tmp/perf-%d.map" % (pid,), "r")
|
|
jitmap = jitmap_file.read()
|
|
jitmap_file.close()
|
|
return jitmap
|
|
|
|
def jit_functions():
|
|
jitmap = jitmap_raw()
|
|
|
|
functions = []
|
|
for line in jitmap.strip().split("\n"):
|
|
[addr, size, name] = line.split(" ")
|
|
functions.append((int(addr, 16), int(size, 16), name))
|
|
|
|
return functions
|
|
|
|
class JitDecorator(gdb.FrameDecorator.FrameDecorator):
|
|
def __init__(self, fobj, name):
|
|
super(JitDecorator, self).__init__(fobj)
|
|
self.name = name
|
|
|
|
def function(self):
|
|
return self.name
|
|
|
|
class JitFilter:
|
|
"""
|
|
A backtrace filter which reads perf map files produced by cranelift-jit.
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.name = 'JitFilter'
|
|
self.enabled = True
|
|
self.priority = 0
|
|
|
|
gdb.current_progspace().frame_filters[self.name] = self
|
|
|
|
# FIXME add an actual unwinder or somehow register JITed .eh_frame with gdb to avoid relying on
|
|
# gdb unwinder heuristics.
|
|
def filter(self, frame_iter):
|
|
for frame in frame_iter:
|
|
frame_addr = frame.inferior_frame().pc()
|
|
for (addr, size, name) in jit_functions():
|
|
if frame_addr >= addr and frame_addr < addr + size:
|
|
yield JitDecorator(frame, name)
|
|
break
|
|
else:
|
|
yield frame
|
|
|
|
JitFilter()
|