Index: Source/platform/heap/ThreadState.cpp |
diff --git a/Source/platform/heap/ThreadState.cpp b/Source/platform/heap/ThreadState.cpp |
index c2f084bfb62eb986ef8d83159ae9634340eabdd0..5392886032fb4090466c24130fd62d3923fcc9c6 100644 |
--- a/Source/platform/heap/ThreadState.cpp |
+++ b/Source/platform/heap/ThreadState.cpp |
@@ -242,6 +242,9 @@ ThreadState::ThreadState() |
, m_inGC(false) |
, m_heapContainsCache(adoptPtr(new HeapContainsCache())) |
, m_isCleaningUp(false) |
+#if defined(ADDRESS_SANITIZER) && !OS(WIN) |
+ , m_asanFakeStack(__asan_get_current_fake_stack()) |
+#endif |
{ |
ASSERT(!**s_threadSpecific); |
**s_threadSpecific = this; |
@@ -344,6 +347,34 @@ void ThreadState::visitRoots(Visitor* visitor) |
} |
NO_SANITIZE_ADDRESS |
+void ThreadState::visitAsanFakeStackForPointer(Visitor* visitor, Address ptr) |
+{ |
+#if defined(ADDRESS_SANITIZER) && !OS(WIN) |
+ Address* start = reinterpret_cast<Address*>(m_startOfStack); |
+ Address* end = reinterpret_cast<Address*>(m_endOfStack); |
+ Address* fakeFrameStart = 0; |
+ Address* fakeFrameEnd = 0; |
+ Address* maybeFakeFrame = reinterpret_cast<Address*>(ptr); |
+ Address* realFrameForFakeFrame = |
+ reinterpret_cast<Address*>( |
+ __asan_addr_is_in_fake_stack( |
+ m_asanFakeStack, maybeFakeFrame, |
+ reinterpret_cast<void**>(&fakeFrameStart), |
+ reinterpret_cast<void**>(&fakeFrameEnd))); |
+ if (realFrameForFakeFrame) { |
+ // This is a fake frame from the asan fake stack. |
+ if (realFrameForFakeFrame > end && start > realFrameForFakeFrame) { |
+ // The real stack address for the asan fake frame is |
+ // within the stack range that we need to scan so we need |
+ // to visit the values in the fake frame. |
+ for (Address* p = fakeFrameStart; p < fakeFrameEnd; p++) |
+ Heap::checkAndMarkPointer(visitor, *p); |
+ } |
+ } |
+#endif |
+} |
+ |
+NO_SANITIZE_ADDRESS |
void ThreadState::visitStack(Visitor* visitor) |
{ |
Address* start = reinterpret_cast<Address*>(m_startOfStack); |
@@ -360,11 +391,15 @@ void ThreadState::visitStack(Visitor* visitor) |
// will read past start address. |
current = reinterpret_cast<Address*>(reinterpret_cast<intptr_t>(current) & ~(sizeof(Address) - 1)); |
- for (; current < start; ++current) |
+ for (; current < start; ++current) { |
Heap::checkAndMarkPointer(visitor, *current); |
+ visitAsanFakeStackForPointer(visitor, *current); |
+ } |
- for (Vector<Address>::iterator it = m_safePointStackCopy.begin(); it != m_safePointStackCopy.end(); ++it) |
+ for (Vector<Address>::iterator it = m_safePointStackCopy.begin(); it != m_safePointStackCopy.end(); ++it) { |
Heap::checkAndMarkPointer(visitor, *it); |
+ visitAsanFakeStackForPointer(visitor, *it); |
+ } |
} |
void ThreadState::visitPersistents(Visitor* visitor) |