[asan] fix unwinding inside libc intercepors (asan issue #46)

llvm-svn: 152768
This commit is contained in:
Kostya Serebryany 2012-03-15 01:36:00 +00:00
parent fd2037162e
commit 54a3cac5c5
5 changed files with 27 additions and 15 deletions

View File

@ -63,12 +63,12 @@ namespace __asan {
// Instruments read/write access to a single byte in memory.
// On error calls __asan_report_error, which aborts the program.
static NOINLINE void AccessAddress(uintptr_t address, bool isWrite) {
if (AddressIsPoisoned(address)) {
GET_BP_PC_SP;
__asan_report_error(pc, bp, sp, address, isWrite, /* access_size */ 1);
}
}
#define ACCESS_ADDRESS(address, isWrite) do { \
if (AddressIsPoisoned(address)) { \
GET_CURRENT_PC_BP_SP; \
__asan_report_error(pc, bp, sp, address, isWrite, /* access_size */ 1); \
} \
} while (0)
// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
// and ASAN_WRITE_RANGE as macro instead of function so
@ -81,8 +81,8 @@ static NOINLINE void AccessAddress(uintptr_t address, bool isWrite) {
#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \
if (size > 0) { \
uintptr_t ptr = (uintptr_t)(offset); \
AccessAddress(ptr, isWrite); \
AccessAddress(ptr + (size) - 1, isWrite); \
ACCESS_ADDRESS(ptr, isWrite); \
ACCESS_ADDRESS(ptr + (size) - 1, isWrite); \
} \
} while (0)

View File

@ -296,12 +296,6 @@ bool WinSymbolize(const void *addr, char *out_buffer, int buffer_size);
typedef thread_return_t (THREAD_CALLING_CONV *thread_callback_t)(void* arg);
#define GET_BP_PC_SP \
uintptr_t bp = GET_CURRENT_FRAME(); \
uintptr_t pc = GET_CALLER_PC(); \
uintptr_t local_stack; \
uintptr_t sp = (uintptr_t)&local_stack;
// These magic values are written to shadow for better error reporting.
const int kAsanHeapLeftRedzoneMagic = 0xfa;
const int kAsanHeapRightRedzoneMagic = 0xfb;

View File

@ -221,7 +221,7 @@ static NOINLINE void DescribeAddress(uintptr_t addr, uintptr_t access_size) {
NOINLINE ASAN_INTERFACE_ATTRIBUTE \
extern "C" void __asan_report_ ## type ## size(uintptr_t addr); \
extern "C" void __asan_report_ ## type ## size(uintptr_t addr) { \
GET_BP_PC_SP; \
GET_CALLER_PC_BP_SP; \
__asan_report_error(pc, bp, sp, addr, is_write, size); \
}

View File

@ -57,6 +57,22 @@ struct AsanStackTrace {
} // namespace __asan
// Use this macro if you want to print stack trace with the caller
// of the current function in the top frame.
#define GET_CALLER_PC_BP_SP \
uintptr_t bp = GET_CURRENT_FRAME(); \
uintptr_t pc = GET_CALLER_PC(); \
uintptr_t local_stack; \
uintptr_t sp = (uintptr_t)&local_stack;
// Use this macro if you want to print stack trace with the current
// function in the top frame.
#define GET_CURRENT_PC_BP_SP \
uintptr_t bp = GET_CURRENT_FRAME(); \
uintptr_t pc = AsanStackTrace::GetCurrentPc(); \
uintptr_t local_stack; \
uintptr_t sp = (uintptr_t)&local_stack;
// Get the stack trace with the given pc and bp.
// The pc will be in the position 0 of the resulting stack trace.
// The bp may refer to the current frame or to the caller's frame.

View File

@ -3,6 +3,8 @@ int main(int argc, char **argv) {
char a1[] = {argc, 2, 3, 4};
char a2[] = {1, 2*argc, 3, 4};
// Check-Common: AddressSanitizer stack-buffer-overflow
// Check-Common: {{#0.*memcmp}}
// Check-Common: {{#1.*main}}
int res = memcmp(a1, a2, 4 + argc); // BOOM
return res;
}