summaryrefslogtreecommitdiff
path: root/lib/lsan
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2016-02-11 18:07:17 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2016-02-11 18:07:17 +0000
commit39e5443dd66951a782e7b3dfa09b93e1568fc7bf (patch)
treeef1fc3ef17195f2886a49efb21bdabff5d79966c /lib/lsan
parent14fc549a107abe6366c0d4c66011dd5cdefac936 (diff)
[LSan] Fix a crash when LSan hits a guard page while scanning thread stack for pointers.
Summary: In some cases stack pointer register (SP) doesn't point into the thread stack: e.g. if one is using swapcontext(). In this case LSan conservatively tries to scan the whole thread stack for pointers. However, thread stack (at least in glibc implementation) may also include guard pages, causing LSan to crash when it's reading from them. One of the solutions is to use a pthread_attr_getguardsize() to adjust the calculated stack boundaries. However, here we're just using IsAccessibleMemoryRange to skip guard pages and make the code (slightly) less platform-specific. Reviewers: kcc Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D17116 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@260554 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/lsan')
-rw-r--r--lib/lsan/lsan_common.cc13
1 files changed, 11 insertions, 2 deletions
diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc
index 0385c37ac..e88853cab 100644
--- a/lib/lsan/lsan_common.cc
+++ b/lib/lsan/lsan_common.cc
@@ -221,9 +221,18 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
LOG_THREADS("Stack at %p-%p (SP = %p).\n", stack_begin, stack_end, sp);
if (sp < stack_begin || sp >= stack_end) {
// SP is outside the recorded stack range (e.g. the thread is running a
- // signal handler on alternate stack). Again, consider the entire stack
- // range to be reachable.
+ // signal handler on alternate stack, or swapcontext was used).
+ // Again, consider the entire stack range to be reachable.
LOG_THREADS("WARNING: stack pointer not in stack range.\n");
+ uptr page_size = GetPageSizeCached();
+ int skipped = 0;
+ while (stack_begin < stack_end &&
+ !IsAccessibleMemoryRange(stack_begin, 1)) {
+ skipped++;
+ stack_begin += page_size;
+ }
+ LOG_THREADS("Skipped %d guard page(s) to obtain stack %p-%p.\n",
+ skipped, stack_begin, stack_end);
} else {
// Shrink the stack range to ignore out-of-scope values.
stack_begin = sp;