forked from OSchip/llvm-project
[asan] move {linux,mac}-specific code from asan_thread.cc to asan_{linux,mac}.cc; also add asan_procmaps.h which I forgot to add on previous commit.
llvm-svn: 147586
This commit is contained in:
parent
6feb3d6650
commit
78d87d3b4b
|
@ -16,11 +16,15 @@
|
|||
#include "asan_interceptors.h"
|
||||
#include "asan_internal.h"
|
||||
#include "asan_procmaps.h"
|
||||
#include "asan_thread.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -150,6 +154,54 @@ bool AsanProcMaps::Next(uint64_t *start, uint64_t *end,
|
|||
return true;
|
||||
}
|
||||
|
||||
void AsanThread::SetThreadStackTopAndBottom() {
|
||||
if (tid() == 0) {
|
||||
// This is the main thread. Libpthread may not be initialized yet.
|
||||
struct rlimit rl;
|
||||
CHECK(getrlimit(RLIMIT_STACK, &rl) == 0);
|
||||
|
||||
// Find the mapping that contains a stack variable.
|
||||
AsanProcMaps proc_maps;
|
||||
uint64_t start, end, offset;
|
||||
uint64_t prev_end = 0;
|
||||
while (proc_maps.Next(&start, &end, &offset, NULL, 0)) {
|
||||
if ((uintptr_t)&rl < end)
|
||||
break;
|
||||
prev_end = end;
|
||||
}
|
||||
CHECK((uintptr_t)&rl >= start && (uintptr_t)&rl < end);
|
||||
|
||||
// Get stacksize from rlimit, but clip it so that it does not overlap
|
||||
// with other mappings.
|
||||
size_t stacksize = rl.rlim_cur;
|
||||
if (stacksize > end - prev_end)
|
||||
stacksize = end - prev_end;
|
||||
if (stacksize > kMaxThreadStackSize)
|
||||
stacksize = kMaxThreadStackSize;
|
||||
stack_top_ = end;
|
||||
stack_bottom_ = end - stacksize;
|
||||
CHECK(AddrIsInStack((uintptr_t)&rl));
|
||||
return;
|
||||
}
|
||||
pthread_attr_t attr;
|
||||
CHECK(pthread_getattr_np(pthread_self(), &attr) == 0);
|
||||
size_t stacksize = 0;
|
||||
void *stackaddr = NULL;
|
||||
pthread_attr_getstack(&attr, &stackaddr, &stacksize);
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
stack_top_ = (uintptr_t)stackaddr + stacksize;
|
||||
stack_bottom_ = (uintptr_t)stackaddr;
|
||||
// When running with unlimited stack size, we still want to set some limit.
|
||||
// The unlimited stack size is caused by 'ulimit -s unlimited'.
|
||||
// Also, for some reason, GNU make spawns subrocesses with unlimited stack.
|
||||
if (stacksize > kMaxThreadStackSize) {
|
||||
stack_bottom_ = stack_top_ - kMaxThreadStackSize;
|
||||
}
|
||||
CHECK(AddrIsInStack((uintptr_t)&attr));
|
||||
}
|
||||
|
||||
|
||||
} // namespace __asan
|
||||
|
||||
#endif // __linux__
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "asan_thread_registry.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <pthread.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -103,6 +104,15 @@ int AsanClose(int fd) {
|
|||
return close(fd);
|
||||
}
|
||||
|
||||
void AsanThread::SetThreadStackTopAndBottom() {
|
||||
size_t stacksize = pthread_get_stacksize_np(pthread_self());
|
||||
void *stackaddr = pthread_get_stackaddr_np(pthread_self());
|
||||
stack_top_ = (uintptr_t)stackaddr;
|
||||
stack_bottom_ = stack_top_ - stacksize;
|
||||
int local;
|
||||
CHECK(AddrIsInStack((uintptr_t)&local));
|
||||
}
|
||||
|
||||
// Support for the following functions from libdispatch on Mac OS:
|
||||
// dispatch_async_f()
|
||||
// dispatch_async()
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
//===-- asan_process.h ------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// Information about the process mappings.
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef ASAN_PROCMAPS_H
|
||||
#define ASAN_PROCMAPS_H
|
||||
|
||||
#include "asan_internal.h"
|
||||
|
||||
namespace __asan {
|
||||
|
||||
class AsanProcMaps {
|
||||
public:
|
||||
AsanProcMaps();
|
||||
bool Next(uint64_t *start, uint64_t *end, uint64_t *offset,
|
||||
char filename[], size_t filename_size);
|
||||
void Reset();
|
||||
~AsanProcMaps();
|
||||
private:
|
||||
#if defined __linux__
|
||||
char *proc_self_maps_buff_;
|
||||
size_t proc_self_maps_buff_mmaped_size_;
|
||||
size_t proc_self_maps_buff_len_;
|
||||
char *current_;
|
||||
#elif defined __APPLE__
|
||||
// FIXME: Mac code goes here
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace __asan
|
||||
|
||||
#endif // ASAN_PROCMAPS_H
|
|
@ -18,8 +18,6 @@
|
|||
#include "asan_thread_registry.h"
|
||||
#include "asan_mapping.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -114,60 +112,4 @@ const char *AsanThread::GetFrameNameByAddr(uintptr_t addr, uintptr_t *offset) {
|
|||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
void AsanThread::SetThreadStackTopAndBottom() {
|
||||
#ifdef __APPLE__
|
||||
size_t stacksize = pthread_get_stacksize_np(pthread_self());
|
||||
void *stackaddr = pthread_get_stackaddr_np(pthread_self());
|
||||
stack_top_ = (uintptr_t)stackaddr;
|
||||
stack_bottom_ = stack_top_ - stacksize;
|
||||
int local;
|
||||
CHECK(AddrIsInStack((uintptr_t)&local));
|
||||
#else
|
||||
if (tid() == 0) {
|
||||
// This is the main thread. Libpthread may not be initialized yet.
|
||||
struct rlimit rl;
|
||||
CHECK(getrlimit(RLIMIT_STACK, &rl) == 0);
|
||||
|
||||
// Find the mapping that contains a stack variable.
|
||||
AsanProcMaps proc_maps;
|
||||
uint64_t start, end, offset;
|
||||
uint64_t prev_end = 0;
|
||||
while (proc_maps.Next(&start, &end, &offset, NULL, 0)) {
|
||||
if ((uintptr_t)&rl < end)
|
||||
break;
|
||||
prev_end = end;
|
||||
}
|
||||
CHECK((uintptr_t)&rl >= start && (uintptr_t)&rl < end);
|
||||
|
||||
// Get stacksize from rlimit, but clip it so that it does not overlap
|
||||
// with other mappings.
|
||||
size_t stacksize = rl.rlim_cur;
|
||||
if (stacksize > end - prev_end)
|
||||
stacksize = end - prev_end;
|
||||
if (stacksize > kMaxThreadStackSize)
|
||||
stacksize = kMaxThreadStackSize;
|
||||
stack_top_ = end;
|
||||
stack_bottom_ = end - stacksize;
|
||||
CHECK(AddrIsInStack((uintptr_t)&rl));
|
||||
return;
|
||||
}
|
||||
pthread_attr_t attr;
|
||||
CHECK(pthread_getattr_np(pthread_self(), &attr) == 0);
|
||||
size_t stacksize = 0;
|
||||
void *stackaddr = NULL;
|
||||
pthread_attr_getstack(&attr, &stackaddr, &stacksize);
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
stack_top_ = (uintptr_t)stackaddr + stacksize;
|
||||
stack_bottom_ = (uintptr_t)stackaddr;
|
||||
// When running with unlimited stack size, we still want to set some limit.
|
||||
// The unlimited stack size is caused by 'ulimit -s unlimited'.
|
||||
// Also, for some reason, GNU make spawns subrocesses with unlimited stack.
|
||||
if (stacksize > kMaxThreadStackSize) {
|
||||
stack_bottom_ = stack_top_ - kMaxThreadStackSize;
|
||||
}
|
||||
CHECK(AddrIsInStack((uintptr_t)&attr));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace __asan
|
||||
|
|
Loading…
Reference in New Issue