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_interceptors.h"
|
||||||
#include "asan_internal.h"
|
#include "asan_internal.h"
|
||||||
#include "asan_procmaps.h"
|
#include "asan_procmaps.h"
|
||||||
|
#include "asan_thread.h"
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -150,6 +154,54 @@ bool AsanProcMaps::Next(uint64_t *start, uint64_t *end,
|
||||||
return true;
|
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
|
} // namespace __asan
|
||||||
|
|
||||||
#endif // __linux__
|
#endif // __linux__
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "asan_thread_registry.h"
|
#include "asan_thread_registry.h"
|
||||||
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -103,6 +104,15 @@ int AsanClose(int fd) {
|
||||||
return close(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:
|
// Support for the following functions from libdispatch on Mac OS:
|
||||||
// dispatch_async_f()
|
// dispatch_async_f()
|
||||||
// dispatch_async()
|
// 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_thread_registry.h"
|
||||||
#include "asan_mapping.h"
|
#include "asan_mapping.h"
|
||||||
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -114,60 +112,4 @@ const char *AsanThread::GetFrameNameByAddr(uintptr_t addr, uintptr_t *offset) {
|
||||||
return "UNKNOWN";
|
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
|
} // namespace __asan
|
||||||
|
|
Loading…
Reference in New Issue