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

Commit 1cb84cea authored by Christopher Ferris's avatar Christopher Ferris
Browse files

Add an interface for stopping in certain maps.

Also, change the std::set parameters to std::vector. As jmgao points out,
a small std::set is not really the best choice for performance reasons.

Test: All unit tests pass, enabled the new unwinder and did a kill -3 on
Test: an android process.
Change-Id: I81227d7b79a9b7cf1d54fb0e3331d3cf4d4d3c4f
parent 09123383
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -45,12 +45,12 @@


bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map,
bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map,
                       std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames) {
                       std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames) {
  static std::set<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"};
  static std::vector<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"};
  UnwindStackMap* stack_map = reinterpret_cast<UnwindStackMap*>(back_map);
  UnwindStackMap* stack_map = reinterpret_cast<UnwindStackMap*>(back_map);
  auto process_memory = stack_map->process_memory();
  auto process_memory = stack_map->process_memory();
  unwindstack::Unwinder unwinder(MAX_BACKTRACE_FRAMES + num_ignore_frames, stack_map->stack_maps(),
  unwindstack::Unwinder unwinder(MAX_BACKTRACE_FRAMES + num_ignore_frames, stack_map->stack_maps(),
                                 regs, stack_map->process_memory());
                                 regs, stack_map->process_memory());
  unwinder.Unwind(&skip_names);
  unwinder.Unwind(&skip_names, &stack_map->GetSuffixesToIgnore());


  if (num_ignore_frames >= unwinder.NumFrames()) {
  if (num_ignore_frames >= unwinder.NumFrames()) {
    frames->resize(0);
    frames->resize(0);
+9 −2
Original line number Original line Diff line number Diff line
@@ -107,13 +107,20 @@ public:
    return map.end > 0;
    return map.end > 0;
  }
  }


  void SetSuffixesToIgnore(std::vector<std::string> suffixes) {
    suffixes_to_ignore_.insert(suffixes_to_ignore_.end(), suffixes.begin(), suffixes.end());
  }

  const std::vector<std::string>& GetSuffixesToIgnore() { return suffixes_to_ignore_; }

 protected:
 protected:
  BacktraceMap(pid_t pid);
  BacktraceMap(pid_t pid);


  virtual bool ParseLine(const char* line, backtrace_map_t* map);
  virtual bool ParseLine(const char* line, backtrace_map_t* map);


  std::deque<backtrace_map_t> maps_;
  pid_t pid_;
  pid_t pid_;
  std::deque<backtrace_map_t> maps_;
  std::vector<std::string> suffixes_to_ignore_;
};
};


class ScopedBacktraceMapIteratorLock {
class ScopedBacktraceMapIteratorLock {
+11 −6
Original line number Original line Diff line number Diff line
@@ -22,6 +22,8 @@
#include <sys/types.h>
#include <sys/types.h>
#include <unistd.h>
#include <unistd.h>


#include <algorithm>

#include <android-base/stringprintf.h>
#include <android-base/stringprintf.h>


#include <unwindstack/Elf.h>
#include <unwindstack/Elf.h>
@@ -64,7 +66,8 @@ void Unwinder::FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, bool ad
  }
  }
}
}


static bool ShouldStop(const std::set<std::string>* map_suffixes_to_ignore, std::string& map_name) {
static bool ShouldStop(const std::vector<std::string>* map_suffixes_to_ignore,
                       std::string& map_name) {
  if (map_suffixes_to_ignore == nullptr) {
  if (map_suffixes_to_ignore == nullptr) {
    return false;
    return false;
  }
  }
@@ -72,11 +75,13 @@ static bool ShouldStop(const std::set<std::string>* map_suffixes_to_ignore, std:
  if (pos == std::string::npos) {
  if (pos == std::string::npos) {
    return false;
    return false;
  }
  }
  return map_suffixes_to_ignore->find(map_name.substr(pos + 1)) != map_suffixes_to_ignore->end();

  return std::find(map_suffixes_to_ignore->begin(), map_suffixes_to_ignore->end(),
                   map_name.substr(pos + 1)) != map_suffixes_to_ignore->end();
}
}


void Unwinder::Unwind(const std::set<std::string>* initial_map_names_to_skip,
void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
                      const std::set<std::string>* map_suffixes_to_ignore) {
                      const std::vector<std::string>* map_suffixes_to_ignore) {
  frames_.clear();
  frames_.clear();


  bool return_address_attempt = false;
  bool return_address_attempt = false;
@@ -97,8 +102,8 @@ void Unwinder::Unwind(const std::set<std::string>* initial_map_names_to_skip,
    }
    }


    if (map_info == nullptr || initial_map_names_to_skip == nullptr ||
    if (map_info == nullptr || initial_map_names_to_skip == nullptr ||
        initial_map_names_to_skip->find(basename(map_info->name.c_str())) ==
        std::find(initial_map_names_to_skip->begin(), initial_map_names_to_skip->end(),
            initial_map_names_to_skip->end()) {
                  basename(map_info->name.c_str())) == initial_map_names_to_skip->end()) {
      FillInFrame(map_info, elf, rel_pc, adjust_pc);
      FillInFrame(map_info, elf, rel_pc, adjust_pc);
      // Once a frame is added, stop skipping frames.
      // Once a frame is added, stop skipping frames.
      initial_map_names_to_skip = nullptr;
      initial_map_names_to_skip = nullptr;
+2 −3
Original line number Original line Diff line number Diff line
@@ -21,7 +21,6 @@
#include <sys/types.h>
#include <sys/types.h>


#include <memory>
#include <memory>
#include <set>
#include <string>
#include <string>
#include <vector>
#include <vector>


@@ -60,8 +59,8 @@ class Unwinder {
  }
  }
  ~Unwinder() = default;
  ~Unwinder() = default;


  void Unwind(const std::set<std::string>* initial_map_names_to_skip = nullptr,
  void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr,
              const std::set<std::string>* map_suffixes_to_ignore = nullptr);
              const std::vector<std::string>* map_suffixes_to_ignore = nullptr);


  size_t NumFrames() { return frames_.size(); }
  size_t NumFrames() { return frames_.size(); }


+3 −3
Original line number Original line Diff line number Diff line
@@ -308,8 +308,8 @@ TEST_F(UnwinderTest, verify_frames_skipped) {
  ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
  ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));


  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
  std::set<std::string> skip_set{"libunwind.so", "libanother.so"};
  std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
  unwinder.Unwind(&skip_set);
  unwinder.Unwind(&skip_libs);


  ASSERT_EQ(3U, unwinder.NumFrames());
  ASSERT_EQ(3U, unwinder.NumFrames());


@@ -572,7 +572,7 @@ TEST_F(UnwinderTest, map_ignore_suffixes) {
  ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
  ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));


  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
  std::set<std::string> suffixes{"oat"};
  std::vector<std::string> suffixes{"oat"};
  unwinder.Unwind(nullptr, &suffixes);
  unwinder.Unwind(nullptr, &suffixes);


  ASSERT_EQ(2U, unwinder.NumFrames());
  ASSERT_EQ(2U, unwinder.NumFrames());