Index: Source/heap/ThreadState.cpp |
diff --git a/Source/heap/ThreadState.cpp b/Source/heap/ThreadState.cpp |
index e955142c39f0b452b580234323b5db17d523d097..cf0ff57d237ae3a1b7b196e18824f4f43814776b 100644 |
--- a/Source/heap/ThreadState.cpp |
+++ b/Source/heap/ThreadState.cpp |
@@ -240,6 +240,9 @@ ThreadState::ThreadState() |
, m_noAllocationCount(0) |
, m_inGC(false) |
, m_heapContainsCache(new HeapContainsCache()) |
+#if defined(ADDRESS_SANITIZER) && !OS(WIN) |
+ , m_asanFakeStack(__asan_get_current_fake_stack()) |
+#endif |
{ |
ASSERT(!**s_threadSpecific); |
**s_threadSpecific = this; |
@@ -307,16 +310,51 @@ void ThreadState::visitRoots(Visitor* visitor) |
(*it)->trace(visitor); |
} |
+#if defined(ADDRESS_SANITIZER) && !OS(WIN) |
+NO_SANITIZE_ADDRESS |
kcc1
2014/02/06 13:44:06
I'd put #ifdef inside the function body, this will
Mads Ager (chromium)
2014/02/06 14:15:17
Good idea. Done!
|
+void ThreadState::visitAsanFakeStackForPointer(Visitor* visitor, Address ptr) |
+{ |
+ 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* end = reinterpret_cast<Address*>(m_startOfStack); |
for (Address* current = reinterpret_cast<Address*>(m_endOfStack); current < end; ++current) { |
Heap::checkAndMarkPointer(visitor, *current); |
+#if defined(ADDRESS_SANITIZER) && !OS(WIN) |
+ visitAsanFakeStackForPointer(visitor, *current); |
+#endif |
} |
- 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); |
+#if defined(ADDRESS_SANITIZER) && !OS(WIN) |
+ visitAsanFakeStackForPointer(visitor, *it); |
+#endif |
+ } |
} |
void ThreadState::visitPersistents(Visitor* visitor) |