mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-02 09:16:17 +01:00
gobject.py: Port to gdb 7.7 frame filter API
https://bugzilla.gnome.org/show_bug.cgi?id=623552
This commit is contained in:
parent
430e6fd6ad
commit
20cda557e5
@ -5,16 +5,17 @@ import sys
|
|||||||
|
|
||||||
if sys.version_info[0] >= 3:
|
if sys.version_info[0] >= 3:
|
||||||
long = int
|
long = int
|
||||||
|
|
||||||
try:
|
|
||||||
import gdb.backtrace
|
|
||||||
import gdb.command.backtrace
|
|
||||||
except ImportError:
|
|
||||||
print(os.path.basename(__file__) + ": gdb was not built with "
|
|
||||||
"custom backtrace support, disabling.")
|
|
||||||
HAVE_GDB_BACKTRACE = 0
|
|
||||||
else:
|
else:
|
||||||
HAVE_GDB_BACKTRACE = 1
|
import itertools
|
||||||
|
map = itertools.imap
|
||||||
|
|
||||||
|
# FrameDecorator is new in gdb 7.7, so we adapt to its absence.
|
||||||
|
try:
|
||||||
|
import gdb.FrameDecorator
|
||||||
|
HAVE_GDB_FRAMEDECORATOR = True
|
||||||
|
FrameDecorator = gdb.FrameDecorator.FrameDecorator
|
||||||
|
except ImportError:
|
||||||
|
HAVE_GDB_FRAMEDECORATOR = False
|
||||||
|
|
||||||
# This is not quite right, as local vars may override symname
|
# This is not quite right, as local vars may override symname
|
||||||
def read_global_var (symname):
|
def read_global_var (symname):
|
||||||
@ -106,21 +107,16 @@ def get_signal_name (id):
|
|||||||
return val[id]["name"].string()
|
return val[id]["name"].string()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
class DummyFrame:
|
def frame_name(frame):
|
||||||
def __init__ (self, frame):
|
return str(frame.function())
|
||||||
self.frame = frame
|
|
||||||
|
|
||||||
def name (self):
|
def frame_var(frame, var):
|
||||||
return "signal-emission-dummy"
|
return frame.inferior_frame().read_var(var)
|
||||||
|
|
||||||
def describe (self, stream, full):
|
|
||||||
stream.write (" <...>\n")
|
|
||||||
|
|
||||||
def __getattr__ (self, name):
|
class SignalFrame(FrameDecorator):
|
||||||
return getattr (self.frame, name)
|
|
||||||
|
|
||||||
class SignalFrame:
|
|
||||||
def __init__ (self, frames):
|
def __init__ (self, frames):
|
||||||
|
FrameDecorator.__init__(self, frames[-1])
|
||||||
self.frame = frames[-1]
|
self.frame = frames[-1]
|
||||||
self.frames = frames
|
self.frames = frames
|
||||||
|
|
||||||
@ -129,7 +125,7 @@ class SignalFrame:
|
|||||||
|
|
||||||
def read_var (self, frame, name, array = None):
|
def read_var (self, frame, name, array = None):
|
||||||
try:
|
try:
|
||||||
v = frame.read_var (name)
|
v = frame_var (frame, name)
|
||||||
if v == None or v.is_optimized_out:
|
if v == None or v.is_optimized_out:
|
||||||
return None
|
return None
|
||||||
if array != None:
|
if array != None:
|
||||||
@ -140,7 +136,7 @@ class SignalFrame:
|
|||||||
|
|
||||||
def read_object (self, frame, name, array = None):
|
def read_object (self, frame, name, array = None):
|
||||||
try:
|
try:
|
||||||
v = frame.read_var (name)
|
v = frame_var (frame, name)
|
||||||
if v == None or v.is_optimized_out:
|
if v == None or v.is_optimized_out:
|
||||||
return None
|
return None
|
||||||
v = v.cast (gdb.lookup_type("GObject").pointer())
|
v = v.cast (gdb.lookup_type("GObject").pointer())
|
||||||
@ -161,7 +157,7 @@ class SignalFrame:
|
|||||||
if len(array) == 0:
|
if len(array) == 0:
|
||||||
return "???"
|
return "???"
|
||||||
else:
|
else:
|
||||||
return ' or '.join(set(array))
|
return ' or '.join(set(map(str, array)))
|
||||||
|
|
||||||
def get_detailed_signal_from_frame(self, frame, signal):
|
def get_detailed_signal_from_frame(self, frame, signal):
|
||||||
detail = self.read_var (frame, "detail")
|
detail = self.read_var (frame, "detail")
|
||||||
@ -171,12 +167,12 @@ class SignalFrame:
|
|||||||
else:
|
else:
|
||||||
return detail
|
return detail
|
||||||
|
|
||||||
def describe (self, stream, full):
|
def function (self):
|
||||||
instances = []
|
instances = []
|
||||||
signals = []
|
signals = []
|
||||||
|
|
||||||
for frame in self.frames:
|
for frame in self.frames:
|
||||||
name = frame.name()
|
name = frame_name(frame)
|
||||||
if name == "signal_emit_unlocked_R":
|
if name == "signal_emit_unlocked_R":
|
||||||
self.read_object (frame, "instance", instances)
|
self.read_object (frame, "instance", instances)
|
||||||
node = self.read_var (frame, "node")
|
node = self.read_var (frame, "node")
|
||||||
@ -212,12 +208,15 @@ class SignalFrame:
|
|||||||
instance = self.or_join_array (instances)
|
instance = self.or_join_array (instances)
|
||||||
signal = self.or_join_array (signals)
|
signal = self.or_join_array (signals)
|
||||||
|
|
||||||
stream.write (" <emit signal %s on instance %s>\n" % (signal, instance))
|
return "<emit signal %s on instance %s>" % (signal, instance)
|
||||||
|
|
||||||
def __getattr__ (self, name):
|
def elided (self):
|
||||||
return getattr (self.frame, name)
|
return self.frames[0:-1]
|
||||||
|
|
||||||
class GFrameFilter:
|
def describe (self, stream, full):
|
||||||
|
stream.write (" " + self.function () + "\n")
|
||||||
|
|
||||||
|
class GFrameDecorator:
|
||||||
def __init__ (self, iter):
|
def __init__ (self, iter):
|
||||||
self.queue = []
|
self.queue = []
|
||||||
self.iter = iter
|
self.iter = iter
|
||||||
@ -226,20 +225,20 @@ class GFrameFilter:
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
def fill (self):
|
def fill (self):
|
||||||
while len(self.queue) <= 6:
|
while len(self.queue) <= 8:
|
||||||
try:
|
try:
|
||||||
f = self.iter.next ()
|
f = next(self.iter)
|
||||||
self.queue.append (f)
|
self.queue.append (f)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
return
|
return
|
||||||
|
|
||||||
def find_signal_emission (self):
|
def find_signal_emission (self):
|
||||||
for i in range (min (len(self.queue), 3)):
|
for i in range (min (len(self.queue), 3)):
|
||||||
if self.queue[i].name() == "signal_emit_unlocked_R":
|
if frame_name(self.queue[i]) == "signal_emit_unlocked_R":
|
||||||
return i
|
return i
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
def next (self):
|
def __next__ (self):
|
||||||
# Ensure we have enough frames for a full signal emission
|
# Ensure we have enough frames for a full signal emission
|
||||||
self.fill()
|
self.fill()
|
||||||
|
|
||||||
@ -253,36 +252,41 @@ class GFrameFilter:
|
|||||||
while True:
|
while True:
|
||||||
if start == 0:
|
if start == 0:
|
||||||
break
|
break
|
||||||
prev_name = self.queue[start-1].name()
|
prev_name = frame_name(self.queue[start-1])
|
||||||
if prev_name.find("_marshal_") or prev_name == "g_closure_invoke":
|
if prev_name.find("_marshal_") >= 0 or prev_name == "g_closure_invoke":
|
||||||
start = start - 1
|
start = start - 1
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
end = emission + 1
|
end = emission + 1
|
||||||
while end < len(self.queue):
|
while end < len(self.queue):
|
||||||
if self.queue[end].name() in ["g_signal_emitv",
|
if frame_name(self.queue[end]) in ["g_signal_emitv",
|
||||||
"g_signal_emit_valist",
|
"g_signal_emit_valist",
|
||||||
"g_signal_emit",
|
"g_signal_emit",
|
||||||
"g_signal_emit_by_name"]:
|
"g_signal_emit_by_name",
|
||||||
|
"_g_closure_invoke_va"]:
|
||||||
end = end + 1
|
end = end + 1
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
signal_frames = self.queue[start:end]
|
signal_frames = self.queue[start:end]
|
||||||
new_frames = []
|
new_frames = [SignalFrame(signal_frames)]
|
||||||
for i in range(len(signal_frames)-1):
|
|
||||||
new_frames.append(DummyFrame(signal_frames[i]))
|
|
||||||
new_frames.append(SignalFrame(signal_frames))
|
|
||||||
|
|
||||||
self.queue[start:end] = new_frames
|
self.queue[start:end] = new_frames
|
||||||
|
|
||||||
return self.queue.pop(0)
|
return self.queue.pop(0)
|
||||||
|
|
||||||
|
class GFrameFilter(object):
|
||||||
|
name = 'glib'
|
||||||
|
enabled = True
|
||||||
|
priority = 100
|
||||||
|
|
||||||
|
def filter(self, iterator):
|
||||||
|
return GFrameDecorator(iterator)
|
||||||
|
|
||||||
def register (obj):
|
def register (obj):
|
||||||
if obj == None:
|
if obj == None:
|
||||||
obj = gdb
|
obj = gdb
|
||||||
|
|
||||||
if HAVE_GDB_BACKTRACE:
|
if HAVE_GDB_FRAMEDECORATOR:
|
||||||
gdb.backtrace.push_frame_filter (GFrameFilter)
|
filter = GFrameFilter()
|
||||||
|
obj.frame_filters[filter.name] = filter
|
||||||
obj.pretty_printers.append(pretty_printer_lookup)
|
obj.pretty_printers.append(pretty_printer_lookup)
|
||||||
|
Loading…
Reference in New Issue
Block a user