class FiberManagerPrinter:
"""Print a folly::fibers::Fiber"""
+ fiber_print_limit = 100
+
def __init__(self, fm):
self.fm = fm
active_fibers = collections.OrderedDict()
+ fiber_count = 0
+
while fiber_hook != all_fibers.address:
+ if fiber_count == FiberManagerPrinter.fiber_print_limit:
+ active_fibers["..."] = "..."
+ break
+
fiber = fiber_hook.cast(gdb.lookup_type("int64_t"))
fiber = fiber - gdb.parse_and_eval(
- "(int64_t)&folly::fibers::Fiber::globalListHook_")
+ "(int64_t)&'folly::fibers::Fiber'::globalListHook_")
fiber = fiber.cast(
gdb.lookup_type('folly::fibers::Fiber').pointer()).dereference()
fiber_hook = fiber_hook.dereference()['next_']
+ fiber_count = fiber_count + 1
+
return active_fibers.items()
def to_string(self):
return "folly::fibers::FiberManager"
+class FiberPrintLimitCommand(gdb.Command):
+ def __init__(self):
+ super(FiberPrintLimitCommand, self).__init__(
+ "fiber-print-limit", gdb.COMMAND_USER)
+
+ def invoke(self, arg, from_tty):
+ if not arg:
+ print("New limit has to be passed to 'fiber_print_limit' command")
+ return
+ FiberManagerPrinter.fiber_print_limit = int(arg)
+ print("New fiber limit for FiberManager printer set to " +
+ str(FiberManagerPrinter.fiber_print_limit))
+
+
class FrameId(object):
def __init__(self, sp, pc):
self.sp = sp
def get_fiber_manager_map(evb_type):
- global_cache_type = gdb.lookup_type(
- "folly::fibers::(anonymous namespace)::GlobalCache<" + evb_type + ">")
+ try:
+ # Exception thrown if unable to find type
+ # Probably because of missing debug symbols
+ global_cache_type = gdb.lookup_type(
+ "folly::fibers::(anonymous namespace)::GlobalCache<" + evb_type + ">")
+ except gdb.error:
+ raise gdb.GdbError("Unable to find types. "
+ "Please make sure debug info is available for this binary.\n"
+ "Have you run 'fbload debuginfo_fbpkg'?")
+
global_cache_instance_ptr_ptr = gdb.parse_and_eval(
"&'" + global_cache_type.name + "::instance()::ret'")
- global_cache_instance = global_cache_instance_ptr_ptr.cast(
- global_cache_type.pointer().pointer()).dereference().dereference()
- return global_cache_instance['map_']
+ global_cache_instance_ptr = global_cache_instance_ptr_ptr.cast(
+ global_cache_type.pointer().pointer()).dereference()
+ if global_cache_instance_ptr == 0x0:
+ raise gdb.GdbError("FiberManager map is empty.")
+ global_cache_instance = global_cache_instance_ptr.dereference()
+ return global_cache_instance['map_']
def get_fiber_manager_map_evb():
return get_fiber_manager_map("folly::EventBase")
def load():
gdb.printing.register_pretty_printer(gdb, build_pretty_printer())
gdb.xmethod.register_xmethod_matcher(gdb, FiberXMethodMatcher())
+ FiberPrintLimitCommand()
FiberActivateCommand()
FiberDeactivateCommand()
Shortcut("get_fiber_manager_map_evb", get_fiber_manager_map_evb)