Loading libbacktrace/UnwindStack.cpp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -163,6 +163,9 @@ bool UnwindStackCurrent::UnwindFromContext(size_t num_ignore_frames, void* ucont } } std::vector<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"}; std::vector<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"}; if (!skip_frames_) { skip_names.clear(); } return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames, &skip_names, &error_); return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames, &skip_names, &error_); } } Loading libbacktrace/backtrace_test.cpp +39 −3 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,9 @@ // Number of simultaneous threads running in our forked process. // Number of simultaneous threads running in our forked process. #define NUM_PTRACE_THREADS 5 #define NUM_PTRACE_THREADS 5 // The list of shared libaries that make up the backtrace library. static std::vector<std::string> kBacktraceLibs{"libunwindstack.so", "libbacktrace.so"}; struct thread_t { struct thread_t { pid_t tid; pid_t tid; int32_t state; int32_t state; Loading Loading @@ -256,15 +259,48 @@ TEST(libbacktrace, local_no_unwind_frames) { VERIFY_NO_ERROR(backtrace->GetError().error_code); VERIFY_NO_ERROR(backtrace->GetError().error_code); ASSERT_TRUE(backtrace->NumFrames() != 0); ASSERT_TRUE(backtrace->NumFrames() != 0); // None of the frames should be in the backtrace libraries. for (const auto& frame : *backtrace ) { for (const auto& frame : *backtrace ) { if (BacktraceMap::IsValid(frame.map)) { if (BacktraceMap::IsValid(frame.map)) { const std::string name = basename(frame.map.name.c_str()); const std::string name = basename(frame.map.name.c_str()); ASSERT_TRUE(name != "libunwind.so" && name != "libbacktrace.so") for (const auto& lib : kBacktraceLibs) { << DumpFrames(backtrace.get()); ASSERT_TRUE(name != lib) << DumpFrames(backtrace.get()); } } } } TEST(libbacktrace, local_unwind_frames) { // Verify that a local unwind with the skip frames disabled does include // frames within the backtrace libraries. std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), getpid())); ASSERT_TRUE(backtrace.get() != nullptr); backtrace->SetSkipFrames(false); ASSERT_TRUE(backtrace->Unwind(0)); VERIFY_NO_ERROR(backtrace->GetError().error_code); ASSERT_TRUE(backtrace->NumFrames() != 0); size_t first_frame_non_backtrace_lib = 0; for (const auto& frame : *backtrace) { if (BacktraceMap::IsValid(frame.map)) { const std::string name = basename(frame.map.name.c_str()); bool found = false; for (const auto& lib : kBacktraceLibs) { if (name == lib) { found = true; break; } } } if (!found) { first_frame_non_backtrace_lib = frame.num; break; break; } } } } } ASSERT_NE(0U, first_frame_non_backtrace_lib) << "No frames found in backtrace libraries:\n" << DumpFrames(backtrace.get()); } TEST(libbacktrace, local_trace) { TEST(libbacktrace, local_trace) { ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelBacktrace, nullptr), 0); ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelBacktrace, nullptr), 0); Loading libbacktrace/include/backtrace/Backtrace.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -204,6 +204,9 @@ class Backtrace { std::string GetErrorString(BacktraceUnwindError error); std::string GetErrorString(BacktraceUnwindError error); // Set whether to skip frames in libbacktrace/libunwindstack when doing a local unwind. void SetSkipFrames(bool skip_frames) { skip_frames_ = skip_frames; } protected: protected: Backtrace(pid_t pid, pid_t tid, BacktraceMap* map); Backtrace(pid_t pid, pid_t tid, BacktraceMap* map); Loading @@ -223,6 +226,9 @@ class Backtrace { std::vector<backtrace_frame_data_t> frames_; std::vector<backtrace_frame_data_t> frames_; // Skip frames in libbacktrace/libunwindstack when doing a local unwind. bool skip_frames_ = true; BacktraceUnwindError error_; BacktraceUnwindError error_; }; }; Loading Loading
libbacktrace/UnwindStack.cpp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -163,6 +163,9 @@ bool UnwindStackCurrent::UnwindFromContext(size_t num_ignore_frames, void* ucont } } std::vector<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"}; std::vector<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"}; if (!skip_frames_) { skip_names.clear(); } return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames, &skip_names, &error_); return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames, &skip_names, &error_); } } Loading
libbacktrace/backtrace_test.cpp +39 −3 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,9 @@ // Number of simultaneous threads running in our forked process. // Number of simultaneous threads running in our forked process. #define NUM_PTRACE_THREADS 5 #define NUM_PTRACE_THREADS 5 // The list of shared libaries that make up the backtrace library. static std::vector<std::string> kBacktraceLibs{"libunwindstack.so", "libbacktrace.so"}; struct thread_t { struct thread_t { pid_t tid; pid_t tid; int32_t state; int32_t state; Loading Loading @@ -256,15 +259,48 @@ TEST(libbacktrace, local_no_unwind_frames) { VERIFY_NO_ERROR(backtrace->GetError().error_code); VERIFY_NO_ERROR(backtrace->GetError().error_code); ASSERT_TRUE(backtrace->NumFrames() != 0); ASSERT_TRUE(backtrace->NumFrames() != 0); // None of the frames should be in the backtrace libraries. for (const auto& frame : *backtrace ) { for (const auto& frame : *backtrace ) { if (BacktraceMap::IsValid(frame.map)) { if (BacktraceMap::IsValid(frame.map)) { const std::string name = basename(frame.map.name.c_str()); const std::string name = basename(frame.map.name.c_str()); ASSERT_TRUE(name != "libunwind.so" && name != "libbacktrace.so") for (const auto& lib : kBacktraceLibs) { << DumpFrames(backtrace.get()); ASSERT_TRUE(name != lib) << DumpFrames(backtrace.get()); } } } } TEST(libbacktrace, local_unwind_frames) { // Verify that a local unwind with the skip frames disabled does include // frames within the backtrace libraries. std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), getpid())); ASSERT_TRUE(backtrace.get() != nullptr); backtrace->SetSkipFrames(false); ASSERT_TRUE(backtrace->Unwind(0)); VERIFY_NO_ERROR(backtrace->GetError().error_code); ASSERT_TRUE(backtrace->NumFrames() != 0); size_t first_frame_non_backtrace_lib = 0; for (const auto& frame : *backtrace) { if (BacktraceMap::IsValid(frame.map)) { const std::string name = basename(frame.map.name.c_str()); bool found = false; for (const auto& lib : kBacktraceLibs) { if (name == lib) { found = true; break; } } } if (!found) { first_frame_non_backtrace_lib = frame.num; break; break; } } } } } ASSERT_NE(0U, first_frame_non_backtrace_lib) << "No frames found in backtrace libraries:\n" << DumpFrames(backtrace.get()); } TEST(libbacktrace, local_trace) { TEST(libbacktrace, local_trace) { ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelBacktrace, nullptr), 0); ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelBacktrace, nullptr), 0); Loading
libbacktrace/include/backtrace/Backtrace.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -204,6 +204,9 @@ class Backtrace { std::string GetErrorString(BacktraceUnwindError error); std::string GetErrorString(BacktraceUnwindError error); // Set whether to skip frames in libbacktrace/libunwindstack when doing a local unwind. void SetSkipFrames(bool skip_frames) { skip_frames_ = skip_frames; } protected: protected: Backtrace(pid_t pid, pid_t tid, BacktraceMap* map); Backtrace(pid_t pid, pid_t tid, BacktraceMap* map); Loading @@ -223,6 +226,9 @@ class Backtrace { std::vector<backtrace_frame_data_t> frames_; std::vector<backtrace_frame_data_t> frames_; // Skip frames in libbacktrace/libunwindstack when doing a local unwind. bool skip_frames_ = true; BacktraceUnwindError error_; BacktraceUnwindError error_; }; }; Loading