Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b566e3cb authored by Colin Cross's avatar Colin Cross Committed by Gerrit Code Review
Browse files

Merge "Catch SIGBUS in HeapWalker"

parents 1265bc9c 87315e9d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+9 −3
Original line number Diff line number Diff line
@@ -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),
@@ -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() {}
@@ -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_;
+23 −7
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#include "android-base/macros.h"

#include "Allocator.h"
#include "log.h"

namespace android {
@@ -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_);
@@ -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