Commit 8ef03f99 authored by Kenny Yu's avatar Kenny Yu Committed by Facebook GitHub Bot

ensure normal stack addresses are valid when walking async stacks

Summary: This ensures that when we collect the normal stack traces while collecting the async stack traces, the normal stack addresses are within a valid range. The normal stack addresses may be invalid because some functions may not follow the usual calling convention, for example with TSAN or with Lua FFI calling into C++.

Reviewed By: yfeldblum

Differential Revision: D32108552

fbshipit-source-id: 97b652f5e71b67dfa810549d837c7a0393d7c4cb
parent c8aa2cb7
......@@ -68,6 +68,10 @@ ssize_t getStackTrace(
namespace {
// Heuristic for guessing the maximum stack frame size. This is needed to ensure
// we do not have stack corruption while walking the stack.
constexpr uint64_t kMaxExpectedStackFrameSize = 0x1000000000;
#if FOLLY_HAVE_LIBUNWIND
inline bool getFrameInfo(unw_cursor_t* cursor, uintptr_t& ip) {
......@@ -181,14 +185,18 @@ size_t walkNormalStack(
StackFrame* normalStackFrame,
StackFrame* normalStackFrameStop) {
size_t numFrames = 0;
// Stack frame addresses should increase as we traverse the stack.
// If it doesn't, it means we have stack corruption, or an unusual calling
// convention. In this case, stop walking the stack early to avoid incorrect
// stack walking.
auto* normalStackFrameStart = normalStackFrame;
while (numFrames < maxAddresses && normalStackFrame != nullptr &&
normalStackFrame >= normalStackFrameStart) {
while (numFrames < maxAddresses && normalStackFrame != nullptr) {
auto* normalStackFrameNext = normalStackFrame->parentFrame;
if (!(normalStackFrameNext > normalStackFrame &&
normalStackFrameNext <
normalStackFrame + kMaxExpectedStackFrameSize)) {
// Stack frame addresses should increase as we traverse the stack.
// If it doesn't, it means we have stack corruption, or an unusual calling
// convention. Ensure that each subsequent frame's address is within a
// valid range. If it does not, stop walking the stack early to avoid
// incorrect stack walking.
break;
}
if (normalStackFrameStop != nullptr &&
normalStackFrameNext == normalStackFrameStop) {
// Reached end of normal stack, need to transition to the async stack.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment