Loading libmemunreachable/HeapWalker.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -207,6 +207,6 @@ void HeapWalker::HandleSegFault(ScopedSignalHandler& handler, int signal, siginf } } ScopedSignalHandler::SignalFn ScopedSignalHandler::handler_; Allocator<ScopedSignalHandler::SignalFnMap>::unique_ptr ScopedSignalHandler::handler_map_; } // namespace android libmemunreachable/HeapWalker.h +9 −3 Original line number Diff line number Diff line Loading @@ -52,7 +52,8 @@ class HeapWalker { allocation_bytes_(0), roots_(allocator), root_vals_(allocator), segv_handler_(), sigsegv_handler_(allocator), sigbus_handler_(allocator), walking_ptr_(0), walking_range_{0, 0}, segv_logged_(false), Loading @@ -62,10 +63,14 @@ class HeapWalker { valid_mappings_range_.end = 0; valid_mappings_range_.begin = ~valid_allocations_range_.end; segv_handler_.install( sigsegv_handler_.install( SIGSEGV, [=](ScopedSignalHandler& handler, int signal, siginfo_t* siginfo, void* uctx) { this->HandleSegFault(handler, signal, siginfo, uctx); }); sigbus_handler_.install( SIGBUS, [=](ScopedSignalHandler& handler, int signal, siginfo_t* siginfo, void* uctx) { this->HandleSegFault(handler, signal, siginfo, uctx); }); } ~HeapWalker() {} Loading Loading @@ -106,7 +111,8 @@ class HeapWalker { allocator::vector<Range> roots_; allocator::vector<uintptr_t> root_vals_; ScopedSignalHandler segv_handler_; ScopedSignalHandler sigsegv_handler_; ScopedSignalHandler sigbus_handler_; volatile uintptr_t walking_ptr_; Range walking_range_; bool segv_logged_; Loading libmemunreachable/ScopedSignalHandler.h +23 −7 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include "android-base/macros.h" #include "Allocator.h" #include "log.h" namespace android { Loading @@ -32,17 +33,29 @@ class ScopedSignalHandler { public: using Fn = std::function<void(ScopedSignalHandler&, int, siginfo_t*, void*)>; explicit ScopedSignalHandler() : signal_(-1) {} explicit ScopedSignalHandler(Allocator<ScopedSignalHandler> allocator) : signal_(-1) { if (handler_map_ == nullptr) { Allocator<SignalFnMap> map_allocator = allocator; handler_map_ = map_allocator.make_unique(allocator); } } ~ScopedSignalHandler() { reset(); } template <class F> void install(int signal, F&& f) { if (signal_ != -1) MEM_LOG_ALWAYS_FATAL("ScopedSignalHandler already installed"); handler_ = SignalFn([=](int signal, siginfo_t* si, void* uctx) { f(*this, signal, si, uctx); }); if (handler_map_->find(signal) != handler_map_->end()) { MEM_LOG_ALWAYS_FATAL("ScopedSignalHandler already installed for %d", signal); } (*handler_map_)[signal] = SignalFn([=](int signal, siginfo_t* si, void* uctx) { f(*this, signal, si, uctx); }); struct sigaction act {}; act.sa_sigaction = [](int signal, siginfo_t* si, void* uctx) { handler_(signal, si, uctx); }; act.sa_sigaction = [](int signal, siginfo_t* si, void* uctx) { ((*handler_map_)[signal])(signal, si, uctx); }; act.sa_flags = SA_SIGINFO; int ret = sigaction(signal, &act, &old_act_); Loading @@ -59,19 +72,22 @@ class ScopedSignalHandler { if (ret < 0) { MEM_ALOGE("failed to uninstall segfault handler"); } handler_ = SignalFn{}; handler_map_->erase(signal_); if (handler_map_->empty()) { handler_map_.reset(); } signal_ = -1; } } private: using SignalFn = std::function<void(int, siginfo_t*, void*)>; using SignalFnMap = allocator::unordered_map<int, SignalFn>; DISALLOW_COPY_AND_ASSIGN(ScopedSignalHandler); int signal_; struct sigaction old_act_; // TODO(ccross): to support multiple ScopedSignalHandlers handler_ would need // to be a static map of signals to handlers, but allocated with Allocator. static SignalFn handler_; static Allocator<SignalFnMap>::unique_ptr handler_map_; }; } // namespace android Loading Loading
libmemunreachable/HeapWalker.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -207,6 +207,6 @@ void HeapWalker::HandleSegFault(ScopedSignalHandler& handler, int signal, siginf } } ScopedSignalHandler::SignalFn ScopedSignalHandler::handler_; Allocator<ScopedSignalHandler::SignalFnMap>::unique_ptr ScopedSignalHandler::handler_map_; } // namespace android
libmemunreachable/HeapWalker.h +9 −3 Original line number Diff line number Diff line Loading @@ -52,7 +52,8 @@ class HeapWalker { allocation_bytes_(0), roots_(allocator), root_vals_(allocator), segv_handler_(), sigsegv_handler_(allocator), sigbus_handler_(allocator), walking_ptr_(0), walking_range_{0, 0}, segv_logged_(false), Loading @@ -62,10 +63,14 @@ class HeapWalker { valid_mappings_range_.end = 0; valid_mappings_range_.begin = ~valid_allocations_range_.end; segv_handler_.install( sigsegv_handler_.install( SIGSEGV, [=](ScopedSignalHandler& handler, int signal, siginfo_t* siginfo, void* uctx) { this->HandleSegFault(handler, signal, siginfo, uctx); }); sigbus_handler_.install( SIGBUS, [=](ScopedSignalHandler& handler, int signal, siginfo_t* siginfo, void* uctx) { this->HandleSegFault(handler, signal, siginfo, uctx); }); } ~HeapWalker() {} Loading Loading @@ -106,7 +111,8 @@ class HeapWalker { allocator::vector<Range> roots_; allocator::vector<uintptr_t> root_vals_; ScopedSignalHandler segv_handler_; ScopedSignalHandler sigsegv_handler_; ScopedSignalHandler sigbus_handler_; volatile uintptr_t walking_ptr_; Range walking_range_; bool segv_logged_; Loading
libmemunreachable/ScopedSignalHandler.h +23 −7 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include "android-base/macros.h" #include "Allocator.h" #include "log.h" namespace android { Loading @@ -32,17 +33,29 @@ class ScopedSignalHandler { public: using Fn = std::function<void(ScopedSignalHandler&, int, siginfo_t*, void*)>; explicit ScopedSignalHandler() : signal_(-1) {} explicit ScopedSignalHandler(Allocator<ScopedSignalHandler> allocator) : signal_(-1) { if (handler_map_ == nullptr) { Allocator<SignalFnMap> map_allocator = allocator; handler_map_ = map_allocator.make_unique(allocator); } } ~ScopedSignalHandler() { reset(); } template <class F> void install(int signal, F&& f) { if (signal_ != -1) MEM_LOG_ALWAYS_FATAL("ScopedSignalHandler already installed"); handler_ = SignalFn([=](int signal, siginfo_t* si, void* uctx) { f(*this, signal, si, uctx); }); if (handler_map_->find(signal) != handler_map_->end()) { MEM_LOG_ALWAYS_FATAL("ScopedSignalHandler already installed for %d", signal); } (*handler_map_)[signal] = SignalFn([=](int signal, siginfo_t* si, void* uctx) { f(*this, signal, si, uctx); }); struct sigaction act {}; act.sa_sigaction = [](int signal, siginfo_t* si, void* uctx) { handler_(signal, si, uctx); }; act.sa_sigaction = [](int signal, siginfo_t* si, void* uctx) { ((*handler_map_)[signal])(signal, si, uctx); }; act.sa_flags = SA_SIGINFO; int ret = sigaction(signal, &act, &old_act_); Loading @@ -59,19 +72,22 @@ class ScopedSignalHandler { if (ret < 0) { MEM_ALOGE("failed to uninstall segfault handler"); } handler_ = SignalFn{}; handler_map_->erase(signal_); if (handler_map_->empty()) { handler_map_.reset(); } signal_ = -1; } } private: using SignalFn = std::function<void(int, siginfo_t*, void*)>; using SignalFnMap = allocator::unordered_map<int, SignalFn>; DISALLOW_COPY_AND_ASSIGN(ScopedSignalHandler); int signal_; struct sigaction old_act_; // TODO(ccross): to support multiple ScopedSignalHandlers handler_ would need // to be a static map of signals to handlers, but allocated with Allocator. static SignalFn handler_; static Allocator<SignalFnMap>::unique_ptr handler_map_; }; } // namespace android Loading