diff --git a/src/libfibre/libfibre.so-gdb.py b/src/libfibre/libfibre.so-gdb.py index a2b86968e017424527f3c2bb2d56d1d5cb481526..4753db09baaccb08150fca0d77ef77e3914f511b 100644 --- a/src/libfibre/libfibre.so-gdb.py +++ b/src/libfibre/libfibre.so-gdb.py @@ -2,6 +2,7 @@ # echo add-auto-load-safe-path . >> $HOME/.gdbinit import gdb +from contextlib import contextmanager class FibreSupport(): def __init__(self): @@ -51,7 +52,7 @@ class FibreSupport(): frame.select() return currframe - def set_fibre(arg): + def set_fibre(arg, silent=False): # if current pthread: use current register context if (arg == gdb.parse_and_eval("Context::currStack")): return True @@ -60,7 +61,8 @@ class FibreSupport(): ptr = gdb.Value(arg).cast(ftype) rsp = ptr['stackPointer'] if (rsp == 0): - print("cannot access stack pointer - active in different thread?") + if not silent: + print("cannot access stack pointer - active in different thread?") return False ptype = gdb.lookup_type('uintptr_t').pointer() rsp = rsp + 40 # cf. STACK_PUSH in src/generic/regsave.h @@ -89,6 +91,31 @@ class FibreSupport(): # restore stack frame currframe.select() + # returns frame for fibre + @contextmanager + def get_frame(arg): + currframe = FibreSupport.prep_frame() + # save register context + tmprsp = str(gdb.parse_and_eval("$rsp")).split(None, 1)[0] + tmprbp = str(gdb.parse_and_eval("$rbp")).split(None, 1)[0] + tmprip = str(gdb.parse_and_eval("$rip")).split(None, 1)[0] + result = None + try: + # execute backtrace, if possible + if (FibreSupport.set_fibre(arg, silent=True)): + result = gdb.selected_frame() + yield result + else: + yield None + finally: + # restore register context + gdb.execute("set $rsp = " + str(tmprsp)) + gdb.execute("set $rbp = " + str(tmprbp)) + gdb.execute("set $rip = " + str(tmprip)) + # restore stack frame + currframe.select() + return result + class InfoFibres(gdb.Command): """Print list of fibres""" def __init__(self): @@ -99,9 +126,15 @@ class InfoFibres(gdb.Command): for i in range(len(FibreSupport.list)): print(str(i), "\tFibre", str(FibreSupport.list[i]), end='') if (FibreSupport.list[i] == curr): - print(" (*)") - else: - print() + print(" (*)", end='') + with FibreSupport.get_frame(FibreSupport.list[i]) as frame: + if frame is not None: + sal = frame.find_sal() + symtab = sal.symtab + print(" in ", frame.name(), sep='', end='') + print(" at ", symtab.filename, ":", sal.line, sep='') + else: + print() class Fibre(gdb.Command): def __init__(self):