From b1e4525138d3ca70bad85d990eda13d470637c32 Mon Sep 17 00:00:00 2001 From: Andrii Grynenko Date: Thu, 31 Mar 2016 17:57:14 -0700 Subject: [PATCH] Implement GDB pretty-printers for folly::fibers Summary:This adds basic print functions for FiberManager, Fiber and FiberManager map. It also adds a global list of fibers to FiberManager. Fibers are only removed from that list on Fiber object destruction, so it shouldn't have any perf impact. Inspired by tao/server/scripts/fiber_bt.gdb FiberManager map example: (gdb) print_folly_fiber_manager_map Global FiberManager map has 2 entries. (folly::EventBase*)0x7fffffffdb60 -> (folly::fibers::FiberManager*)0x7ffff5b58480 (folly::EventBase*)0x7fffffffd930 -> (folly::fibers::FiberManager*)0x7ffff5b58300 FiberManager example: (gdb) print_folly_fiber_manager &manager (folly::fibers::FiberManager*)0x7fffffffdbe0 Fibers active: 3 Fibers allocated: 3 Fibers pool size: 0 Active fiber: (folly::fibers::Fiber*)(nil) Current fiber: (folly::fibers::Fiber*)(nil) Active fibers: (folly::fibers::Fiber*)0x7ffff5b5b000 State: Awaiting (folly::fibers::Fiber*)0x7ffff5b5b300 State: Awaiting (folly::fibers::Fiber*)0x7ffff5b5b600 State: Awaiting Fiber example: P56244621 Reviewed By: yfeldblum Differential Revision: D3119616 fb-gh-sync-id: defa27b84aafbd4333b2ca301f07c226f0386f44 fbshipit-source-id: defa27b84aafbd4333b2ca301f07c226f0386f44 --- folly/experimental/fibers/Fiber.cpp | 2 + folly/experimental/fibers/Fiber.h | 1 + folly/experimental/fibers/FiberManager.h | 4 + folly/experimental/fibers/scripts/utils.gdb | 99 +++++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 folly/experimental/fibers/scripts/utils.gdb diff --git a/folly/experimental/fibers/Fiber.cpp b/folly/experimental/fibers/Fiber.cpp index de0e30b8..56b0f3eb 100644 --- a/folly/experimental/fibers/Fiber.cpp +++ b/folly/experimental/fibers/Fiber.cpp @@ -85,6 +85,8 @@ Fiber::Fiber(FiberManager& fiberManager) : auto limit = fiberManager_.stackAllocator_.allocate(size); fcontext_ = makeContext(limit, size, &Fiber::fiberFuncHelper); + + fiberManager_.allFibers_.push_back(*this); } void Fiber::init(bool recordStackUsed) { diff --git a/folly/experimental/fibers/Fiber.h b/folly/experimental/fibers/Fiber.h index f29f5115..39a05fca 100644 --- a/folly/experimental/fibers/Fiber.h +++ b/folly/experimental/fibers/Fiber.h @@ -181,6 +181,7 @@ class Fiber { folly::IntrusiveListHook listHook_; /**< list hook for different FiberManager queues */ + folly::IntrusiveListHook globalListHook_; /**< list hook for global list */ pid_t threadId_{0}; }; diff --git a/folly/experimental/fibers/FiberManager.h b/folly/experimental/fibers/FiberManager.h index 588f8ee4..d9dfef2b 100644 --- a/folly/experimental/fibers/FiberManager.h +++ b/folly/experimental/fibers/FiberManager.h @@ -341,6 +341,8 @@ class FiberManager : public ::folly::Executor { intptr_t deactivateFiber(Fiber* fiber); typedef folly::IntrusiveList FiberTailQueue; + typedef folly::IntrusiveList + GlobalFiberTailQueue; Fiber* activeFiber_{nullptr}; /**< active fiber, nullptr on main context */ /** @@ -354,6 +356,8 @@ class FiberManager : public ::folly::Executor { execution */ FiberTailQueue fibersPool_; /**< pool of unitialized Fiber objects */ + GlobalFiberTailQueue allFibers_; /**< list of all Fiber objects owned */ + size_t fibersAllocated_{0}; /**< total number of fibers allocated */ size_t fibersPoolSize_{0}; /**< total number of fibers in the free pool */ size_t fibersActive_{0}; /**< number of running or blocked fibers */ diff --git a/folly/experimental/fibers/scripts/utils.gdb b/folly/experimental/fibers/scripts/utils.gdb new file mode 100644 index 00000000..ada27fe8 --- /dev/null +++ b/folly/experimental/fibers/scripts/utils.gdb @@ -0,0 +1,99 @@ +# Print given Fiber state +# arg0 folly::fibers::Fiber* +define print_folly_fiber_state + set $fiber = (folly::fibers::Fiber*)$arg0 + if $fiber->state_ == folly::fibers::Fiber::INVALID + printf "Invalid" + end + if $fiber->state_ == folly::fibers::Fiber::NOT_STARTED + printf "Not started" + end + if $fiber->state_ == folly::fibers::Fiber::READY_TO_RUN + printf "Ready to run" + end + if $fiber->state_ == folly::fibers::Fiber::RUNNING + printf "Running" + end + if $fiber->state_ == folly::fibers::Fiber::AWAITING + printf "Awaiting" + end + if $fiber->state_ == folly::fibers::Fiber::AWAITING_IMMEDIATE + printf "Awaiting immediate" + end + if $fiber->state_ == folly::fibers::Fiber::YIELDED + printf "Yielded" + end +end + +# Print given Fiber +# arg0 folly::fibers::Fiber* +define print_folly_fiber + set $fiber = (folly::fibers::Fiber*)$arg0 + printf " (folly::fibers::Fiber*)%p\n\n", $fiber + + printf " State: " + print_folly_fiber_state $fiber + printf "\n" + + if $fiber->state_ != folly::fibers::Fiber::INVALID && \ + $fiber->state_ != folly::fibers::Fiber::NOT_STARTED && \ + $fiber->state_ != folly::fibers::Fiber::RUNNING + printf " Backtrace:\n" + set $frameptr = ((uint64_t*)$fiber->fcontext_.context_)[6] + set $k = 0 + while $frameptr != 0 + printf " #%d at %p in ", $k, *((void**)($frameptr+8)) + set $k = $k + 1 + info symbol *((void**)($frameptr+8)) + set $frameptr = *((void**)($frameptr)) + end + end +end + +# Print given FiberManager +# arg0 folly::fibers::FiberManager* +define print_folly_fiber_manager + set $fiberManager = (folly::fibers::FiberManager*)$arg0 + + printf " (folly::fibers::FiberManager*)%p\n\n", $fiberManager + printf " Fibers active: %d\n", $fiberManager->fibersActive_ + printf " Fibers allocated: %d\n", $fiberManager->fibersAllocated_ + printf " Fibers pool size: %d\n", $fiberManager->fibersPoolSize_ + printf " Active fiber: (folly::fibers::Fiber*)%p\n", \ + $fiberManager->activeFiber_ + printf " Current fiber: (folly::fibers::Fiber*)%p\n", \ + $fiberManager->currentFiber_ + + set $all_fibers = &($fiberManager->allFibers_.data_.root_plus_size_.m_header) + set $fiber_hook = $all_fibers->next_ + printf "\n Active fibers:\n" + while $fiber_hook != $all_fibers + set $fiber = (folly::fibers::Fiber*) \ + ((int64_t)$fiber_hook - \ + (int64_t)&folly::fibers::Fiber::globalListHook_) + if $fiber->state_ != folly::fibers::Fiber::INVALID + printf " (folly::fibers::Fiber*)%p State: ", $fiber + print_folly_fiber_state $fiber + printf "\n" + end + set $fiber_hook = $fiber_hook->next_ + end +end + +# Print global FiberManager map +define print_folly_fiber_manager_map + set $global_cache=*(('folly::fibers::(anonymous namespace)::GlobalCache'**) \ + &'folly::fibers::(anonymous namespace)::GlobalCache::instance()::ret') + printf " Global FiberManager map has %d entries.\n", \ + $global_cache->map_->_M_h->_M_element_count + + set $item = $global_cache->map_->_M_h->_M_before_begin._M_nxt + while $item != 0 + set $evb = ((folly::EventBase**)$item)[1] + set $fiberManager = ((folly::fibers::FiberManager**)$item)[2] + printf " (folly::EventBase*)%p -> (folly::fibers::FiberManager*)%p\n", \ + $evb, $fiberManager + + set $item = $item->_M_nxt + end +end -- 2.34.1