Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,74 @@
// RUN: %clang_esan_wset -O0 %s -o %t 2>&1
// RUN: %env_esan_opts="verbosity=1 record_snapshots=0" %run %t %t 2>&1 | FileCheck %s
#include <assert.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
static void testChildStackLimit(rlim_t StackLimit, char *ToRun) {
int Res;
struct rlimit Limit;
Limit.rlim_cur = RLIM_INFINITY;
Limit.rlim_max = RLIM_INFINITY;
Res = setrlimit(RLIMIT_STACK, &Limit);
if (Res != 0) {
// Probably our environment had a large limit and we ourselves got
// re-execed and can no longer raise our limit.
// We have to bail and emulate the regular test.
// We'd prefer to have branches in our FileCheck output to ensure the
// initial program was re-execed but this is the best we can do for now.
fprintf(stderr, "in esan::initializeLibrary\n");
fprintf(stderr, "==1234==The stack size limit is beyond the maximum supported.\n");
fprintf(stderr, "Re-execing with a stack size below 1TB.\n");
fprintf(stderr, "in esan::initializeLibrary\n");
fprintf(stderr, "done\n");
fprintf(stderr, "in esan::finalizeLibrary\n");
return;
}
pid_t Child = fork();
assert(Child >= 0);
if (Child > 0) {
pid_t WaitRes = waitpid(Child, NULL, 0);
assert(WaitRes == Child);
} else {
char *Args[2];
Args[0] = ToRun;
Args[1] = NULL;
Res = execv(ToRun, Args);
assert(0); // Should not be reached.
}
}
int main(int argc, char *argv[]) {
// The path to the program to exec must be passed in the first time.
if (argc == 2) {
fprintf(stderr, "Testing child with infinite stack\n");
testChildStackLimit(RLIM_INFINITY, argv[1]);
fprintf(stderr, "Testing child with 1TB stack\n");
testChildStackLimit(1ULL << 40, argv[1]);
}
fprintf(stderr, "done\n");
// CHECK: in esan::initializeLibrary
// CHECK: Testing child with infinite stack
// CHECK-NEXT: in esan::initializeLibrary
// CHECK-NEXT: =={{[0-9:]+}}==The stack size limit is beyond the maximum supported.
// CHECK-NEXT: Re-execing with a stack size below 1TB.
// CHECK-NEXT: in esan::initializeLibrary
// CHECK: done
// CHECK: in esan::finalizeLibrary
// CHECK: Testing child with 1TB stack
// CHECK-NEXT: in esan::initializeLibrary
// CHECK-NEXT: =={{[0-9:]+}}==The stack size limit is beyond the maximum supported.
// CHECK-NEXT: Re-execing with a stack size below 1TB.
// CHECK-NEXT: in esan::initializeLibrary
// CHECK: done
// CHECK-NEXT: in esan::finalizeLibrary
// CHECK: done
// CHECK-NEXT: in esan::finalizeLibrary
return 0;
}

View File

@@ -0,0 +1,20 @@
// RUN: %clang_esan_frag -O0 %s -o %t 2>&1
// RUN: %env_esan_opts=verbosity=3 %run %t 2>&1 | FileCheck %s
#include <string.h>
int main(int argc, char **argv) {
char Buf[2048];
const char Str[] = "TestStringOfParticularLength"; // 29 chars.
strcpy(Buf, Str);
strncpy(Buf, Str, 17);
return strncmp(Buf, Str, 17);
// CHECK: in esan::initializeLibrary
// CHECK: in esan::processRangeAccess {{.*}} 29
// CHECK: in esan::processRangeAccess {{.*}} 29
// CHECK: in esan::processRangeAccess {{.*}} 17
// CHECK: in esan::processRangeAccess {{.*}} 17
// CHECK: in esan::processRangeAccess {{.*}} 17
// CHECK: in esan::processRangeAccess {{.*}} 17
// CHECK: in esan::finalizeLibrary
}

View File

@@ -0,0 +1,44 @@
// RUN: %clang_esan_frag -O0 %s -o %t 2>&1
// RUN: %env_esan_opts=verbosity=1 %run %t 2>&1 | FileCheck --check-prefix=%arch --check-prefix=CHECK %s
#include <unistd.h>
#include <sys/mman.h>
#include <stdio.h>
int main(int argc, char **argv) {
#if defined(__mips64)
void *Map = mmap((void *)0x0000001600000000ULL, 0x1000, PROT_READ,
MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
#else
void *Map = mmap((void *)0x0000016000000000ULL, 0x1000, PROT_READ,
MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
#endif
if (Map == (void *)-1)
fprintf(stderr, "map failed\n");
else
fprintf(stderr, "mapped %p\n", Map);
#if defined(__mips64)
Map = mmap((void *)0x0000001600000000ULL, 0x1000, PROT_READ,
MAP_ANON|MAP_PRIVATE, -1, 0);
#else
Map = mmap((void *)0x0000016000000000ULL, 0x1000, PROT_READ,
MAP_ANON|MAP_PRIVATE, -1, 0);
#endif
fprintf(stderr, "mapped %p\n", Map);
// CHECK: in esan::initializeLibrary
// (There can be a re-exec for stack limit here.)
// x86_64: Shadow scale=2 offset=0x440000000000
// x86_64-NEXT: Shadow #0: [110000000000-114000000000) (256GB)
// x86_64-NEXT: Shadow #1: [124000000000-12c000000000) (512GB)
// x86_64-NEXT: Shadow #2: [148000000000-150000000000) (512GB)
// mips64: Shadow scale=2 offset=0x4400000000
// mips64-NEXT: Shadow #0: [1140000000-1180000000) (1GB)
// mips64-NEXT: Shadow #1: [1380000000-13c0000000) (1GB)
// mips64-NEXT: Shadow #2: [14c0000000-1500000000) (1GB)
// CHECK-NEXT: mmap conflict: {{.*}}
// CHECK-NEXT: map failed
// CHECK-NEXT: mmap conflict: {{.*}}
// CHECK-NEXT: mapped {{.*}}
// CHECK-NEXT: in esan::finalizeLibrary
return 0;
}

View File

@@ -0,0 +1,204 @@
// RUN: %clang_esan_frag -O0 %s -DPART1 -mllvm -esan-aux-field-info=0 -c -o %t-part1.o 2>&1
// RUN: %clang_esan_frag -O0 %s -DPART2 -c -o %t-part2.o 2>&1
// RUN: %clang_esan_frag -O0 %s -DMAIN -c -o %t-main.o 2>&1
// RUN: %clang_esan_frag -O0 %t-part1.o %t-part2.o %t-main.o -o %t 2>&1
// RUN: %env_esan_opts=verbosity=2 %run %t 2>&1 | FileCheck %s
// We generate two different object files from this file with different
// macros, and then link them together. We do this to test how we handle
// separate compilation with multiple compilation units.
#include <stdio.h>
extern "C" {
void part1();
void part2();
}
//===-- compilation unit part1 without main function ----------------------===//
#ifdef PART1
struct A {
int x;
int y;
};
struct B {
float m;
double n;
};
union U {
float f;
double d;
};
// Same struct in both main and part1.
struct S {
int s1;
int s2;
};
// Different structs with the same name in main and part1.
struct D {
int d1;
int d2;
struct {
int x;
int y;
int z;
} ds[10];
};
void part1()
{
struct A a;
struct B b;
union U u;
struct S s;
struct D d;
for (int i = 0; i < (1 << 11); i++)
a.x = 0;
a.y = 1;
b.m = 2.0;
for (int i = 0; i < (1 << 21); i++) {
b.n = 3.0;
d.ds[3].y = 0;
}
u.f = 0.0;
u.d = 1.0;
s.s1 = 0;
d.d1 = 0;
}
#endif // PART1
//===-- compilation unit part2 without main function ----------------------===//
#ifdef PART2
// No struct in this part.
void part2()
{
// do nothing
}
#endif // PART2
//===-- compilation unit with main function -------------------------------===//
#ifdef MAIN
class C {
public:
struct {
int x;
int y;
} cs;
union {
float f;
double d;
} cu;
char c[10];
};
// Same struct in both main and part1.
struct S {
int s1;
int s2;
};
// Different structs with the same name in main and part1.
struct D {
int d1;
int d2;
int d3;
};
int main(int argc, char **argv) {
// CHECK: in esan::initializeLibrary
// CHECK: in esan::initializeCacheFrag
// CHECK-NEXT: in esan::processCompilationUnitInit
// CHECK-NEXT: in esan::processCacheFragCompilationUnitInit: {{.*}}struct-simple.cpp with 6 class(es)/struct(s)
// CHECK-NEXT: Register struct.A$2$11$11: 2 fields
// CHECK-NEXT: Register struct.B$2$3$2: 2 fields
// CHECK-NEXT: Register union.U$1$3: 1 fields
// CHECK-NEXT: Register struct.S$2$11$11: 2 fields
// CHECK-NEXT: Register struct.D$3$14$11$11: 3 fields
// CHECK-NEXT: Register struct.anon$3$11$11$11: 3 fields
// CHECK-NEXT: in esan::processCompilationUnitInit
// CHECK-NEXT: in esan::processCacheFragCompilationUnitInit: {{.*}}struct-simple.cpp with 0 class(es)/struct(s)
// CHECK-NEXT: in esan::processCompilationUnitInit
// CHECK-NEXT: in esan::processCacheFragCompilationUnitInit: {{.*}}struct-simple.cpp with 5 class(es)/struct(s)
// CHECK-NEXT: Register class.C$3$14$13$13: 3 fields
// CHECK-NEXT: Register struct.anon$2$11$11: 2 fields
// CHECK-NEXT: Register union.anon$1$3: 1 fields
// CHECK-NEXT: Duplicated struct.S$2$11$11: 2 fields
// CHECK-NEXT: Register struct.D$3$11$11$11: 3 fields
struct C c[2];
struct S s;
struct D d;
c[0].cs.x = 0;
c[1].cs.y = 1;
c[0].cu.f = 0.0;
c[1].cu.d = 1.0;
c[0].c[2] = 0;
s.s1 = 0;
d.d1 = 0;
d.d2 = 0;
part1();
part2();
return 0;
// CHECK: in esan::finalizeLibrary
// CHECK-NEXT: in esan::finalizeCacheFrag
// CHECK-NEXT: in esan::processCompilationUnitExit
// CHECK-NEXT: in esan::processCacheFragCompilationUnitExit: {{.*}}struct-simple.cpp with 5 class(es)/struct(s)
// CHECK-NEXT: Unregister class.C$3$14$13$13: 3 fields
// CHECK-NEXT: {{.*}} class C
// CHECK-NEXT: {{.*}} size = 32, count = 5, ratio = 3, array access = 5
// CHECK-NEXT: {{.*}} # 0: offset = 0, size = 8, count = 2, type = %struct.anon = type { i32, i32 }
// CHECK-NEXT: {{.*}} # 1: offset = 8, size = 8, count = 2, type = %union.anon = type { double }
// CHECK-NEXT: {{.*}} # 2: offset = 16, size = 10, count = 1, type = [10 x i8]
// CHECK-NEXT: Unregister struct.anon$2$11$11: 2 fields
// CHECK-NEXT: {{.*}} struct anon
// CHECK-NEXT: {{.*}} size = 8, count = 2, ratio = 1, array access = 0
// CHECK-NEXT: {{.*}} # 0: offset = 0, size = 4, count = 1, type = i32
// CHECK-NEXT: {{.*}} # 1: offset = 4, size = 4, count = 1, type = i32
// CHECK-NEXT: Unregister union.anon$1$3: 1 fields
// CHECK-NEXT: Unregister struct.S$2$11$11: 2 fields
// CHECK-NEXT: {{.*}} struct S
// CHECK-NEXT: {{.*}} size = 8, count = 2, ratio = 2, array access = 0
// CHECK-NEXT: {{.*}} # 0: count = 2
// CHECK-NEXT: {{.*}} # 1: count = 0
// CHECK-NEXT: Unregister struct.D$3$11$11$11: 3 fields
// CHECK-NEXT: {{.*}} struct D
// CHECK-NEXT: {{.*}} size = 12, count = 2, ratio = 2, array access = 0
// CHECK-NEXT: {{.*}} # 0: offset = 0, size = 4, count = 1, type = i32
// CHECK-NEXT: {{.*}} # 1: offset = 4, size = 4, count = 1, type = i32
// CHECK-NEXT: {{.*}} # 2: offset = 8, size = 4, count = 0, type = i32
// CHECK-NEXT: in esan::processCompilationUnitExit
// CHECK-NEXT: in esan::processCacheFragCompilationUnitExit: {{.*}}struct-simple.cpp with 0 class(es)/struct(s)
// CHECK-NEXT: in esan::processCompilationUnitExit
// CHECK-NEXT: in esan::processCacheFragCompilationUnitExit: {{.*}}struct-simple.cpp with 6 class(es)/struct(s)
// CHECK-NEXT: Unregister struct.A$2$11$11: 2 fields
// CHECK-NEXT: {{.*}} struct A
// CHECK-NEXT: {{.*}} size = 8, count = 2049, ratio = 2048, array access = 0
// CHECK-NEXT: {{.*}} # 0: count = 2048
// CHECK-NEXT: {{.*}} # 1: count = 1
// CHECK-NEXT: Unregister struct.B$2$3$2: 2 fields
// CHECK-NEXT: {{.*}} struct B
// CHECK-NEXT: {{.*}} size = 16, count = 2097153, ratio = 2097152, array access = 0
// CHECK-NEXT: {{.*}} # 0: count = 1
// CHECK-NEXT: {{.*}} # 1: count = 2097152
// CHECK-NEXT: Unregister union.U$1$3: 1 fields
// CHECK-NEXT: Duplicated struct.S$2$11$11: 2 fields
// CHECK-NEXT: Unregister struct.D$3$14$11$11: 3 fields
// CHECK-NEXT: {{.*}} struct D
// CHECK-NEXT: {{.*}} size = 128, count = 2097153, ratio = 2097153, array access = 0
// CHECK-NEXT: {{.*}} # 0: count = 1
// CHECK-NEXT: {{.*}} # 1: count = 0
// CHECK-NEXT: {{.*}} # 2: count = 2097152
// CHECK-NEXT: Unregister struct.anon$3$11$11$11: 3 fields
// CHECK-NEXT: {{.*}} struct anon
// CHECK-NEXT: {{.*}} size = 12, count = 2097152, ratio = 4194304, array access = 2097152
// CHECK-NEXT: {{.*}} # 0: count = 0
// CHECK-NEXT: {{.*}} # 1: count = 2097152
// CHECK-NEXT: {{.*}} # 2: count = 0
// CHECK-NEXT: {{.*}}EfficiencySanitizer: total struct field access count = 6293518
}
#endif // MAIN

View File

@@ -0,0 +1,18 @@
// RUN: %clang_esan_frag -O0 %s -o %t 2>&1
// RUN: %env_esan_opts="verbosity=1 log_exe_name=1" %run %t 2>&1 | FileCheck --check-prefix=%arch --check-prefix=CHECK %s
int main(int argc, char **argv) {
// CHECK: in esan::initializeLibrary
// (There can be a re-exec for stack limit here.)
// x86_64: Shadow scale=2 offset=0x440000000000
// x86_64-NEXT: Shadow #0: [110000000000-114000000000) (256GB)
// x86_64-NEXT: Shadow #1: [124000000000-12c000000000) (512GB)
// x86_64-NEXT: Shadow #2: [148000000000-150000000000) (512GB)
// mips64: Shadow scale=2 offset=0x4400000000
// mips64-NEXT: Shadow #0: [1140000000-1180000000) (1GB)
// mips64-NEXT: Shadow #1: [1380000000-13c0000000) (1GB)
// mips64-NEXT: Shadow #2: [14c0000000-1500000000) (1GB)
// CHECK: in esan::finalizeLibrary
// CHECK: ==verbose-simple{{.*}}EfficiencySanitizer: total struct field access count = 0
return 0;
}

View File

@@ -0,0 +1,33 @@
// Test shadow faults during esan initialization as well as
// faults during dlsym's calloc during interceptor init.
//
// RUN: %clang_esan_wset %s -o %t
// RUN: %run %t 2>&1 | FileCheck %s
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Our goal is to emulate an instrumented allocator, whose calloc
// invoked from dlsym will trigger shadow faults, to test an
// early shadow fault during esan interceptor init.
// We do this by replacing calloc:
void *calloc(size_t size, size_t n) {
// Unfortunately we can't print anything to make the test
// ensure we got here b/c the sanitizer interceptors can't
// handle that during interceptor init.
// Ensure we trigger a shadow write fault:
int x[16];
x[0] = size;
// Now just emulate calloc.
void *res = malloc(size*n);
memset(res, 0, size*n);
return res;
}
int main(int argc, char **argv) {
printf("all done\n");
return 0;
}
// CHECK: all done

View File

@@ -0,0 +1,20 @@
// RUN: %clang_esan_wset -O0 %s -o %t 2>&1
// RUN: %run %t 2>&1 | FileCheck %s
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <assert.h>
#include <string.h>
int main(int argc, char **argv) {
const int size = 128*1024*1024;
char *p = (char *)mmap(0, size, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);
// Test the slowpath at different cache line boundaries.
for (int i = 0; i < 630; i++)
memset((char *)p + 63*i, i, 63*i);
munmap(p, size);
return 0;
// CHECK: {{.*}} EfficiencySanitizer: the total working set size: 77 KB (12{{[0-9]+}} cache lines)
}

View File

@@ -0,0 +1,74 @@
// RUN: %clang_esan_wset -O0 %s -o %t 2>&1
// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN
// RUN: %clang -O0 %s -o %t 2>&1
// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ESAN
// FIXME: Re-enable once PR33590 is fixed.
// UNSUPPORTED: x86_64
#include <sanitizer/esan_interface.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
const int size = 0x1 << 25; // 523288 cache lines
const int iters = 6;
int main(int argc, char **argv) {
char *buf = (char *)mmap(0, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
// To avoid flakiness stemming from whether the sideline thread
// is scheduled enough on a loaded test machine, we coordinate
// with esan itself:
if (__esan_get_sample_count) {
while (__esan_get_sample_count() < 4) {
for (int i = 0; i < size; ++i)
buf[i] = i;
sched_yield();
}
}
// Ensure a non-esan build works without ifdefs:
if (__esan_report) {
// We should get 2 roughly identical reports:
__esan_report();
}
munmap(buf, size);
fprintf(stderr, "all done\n");
// CHECK-NO-ESAN: all done
// We only check for a few samples here to reduce the chance of flakiness:
// CHECK-ESAN: =={{[0-9]+}}== Total number of samples: {{[0-9]+}}
// CHECK-ESAN-NEXT: =={{[0-9]+}}== Samples array #0 at period 20 ms
// CHECK-ESAN-NEXT: =={{[0-9]+}}==# 0: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK-ESAN-NEXT: =={{[0-9]+}}==# 1: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK-ESAN-NEXT: =={{[0-9]+}}==# 2: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK-ESAN-NEXT: =={{[0-9]+}}==# 3: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK-ESAN: =={{[0-9]+}}== Samples array #1 at period 80 ms
// CHECK-ESAN-NEXT: =={{[0-9]+}}==# 0: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK-ESAN: =={{[0-9]+}}== Samples array #2 at period 320 ms
// CHECK-ESAN: =={{[0-9]+}}== Samples array #3 at period 1280 ms
// CHECK-ESAN: =={{[0-9]+}}== Samples array #4 at period 5120 ms
// CHECK-ESAN: =={{[0-9]+}}== Samples array #5 at period 20 sec
// CHECK-ESAN: =={{[0-9]+}}== Samples array #6 at period 81 sec
// CHECK-ESAN: =={{[0-9]+}}== Samples array #7 at period 327 sec
// CHECK-ESAN: {{.*}} EfficiencySanitizer: the total working set size: 32 MB (5242{{[0-9][0-9]}} cache lines)
// CHECK-ESAN-NEXT: all done
// CHECK-ESAN-NEXT: =={{[0-9]+}}== Total number of samples: {{[0-9]+}}
// CHECK-ESAN-NEXT: =={{[0-9]+}}== Samples array #0 at period 20 ms
// CHECK-ESAN-NEXT: =={{[0-9]+}}==# 0: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK-ESAN-NEXT: =={{[0-9]+}}==# 1: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK-ESAN-NEXT: =={{[0-9]+}}==# 2: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK-ESAN-NEXT: =={{[0-9]+}}==# 3: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK-ESAN: =={{[0-9]+}}== Samples array #1 at period 80 ms
// CHECK-ESAN-NEXT: =={{[0-9]+}}==# 0: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK-ESAN: =={{[0-9]+}}== Samples array #2 at period 320 ms
// CHECK-ESAN: =={{[0-9]+}}== Samples array #3 at period 1280 ms
// CHECK-ESAN: =={{[0-9]+}}== Samples array #4 at period 5120 ms
// CHECK-ESAN: =={{[0-9]+}}== Samples array #5 at period 20 sec
// CHECK-ESAN: =={{[0-9]+}}== Samples array #6 at period 81 sec
// CHECK-ESAN: =={{[0-9]+}}== Samples array #7 at period 327 sec
// CHECK-ESAN: {{.*}} EfficiencySanitizer: the total working set size: 32 MB (5242{{[0-9][0-9]}} cache lines)
return 0;
}

View File

@@ -0,0 +1,46 @@
// RUN: %clang_esan_wset -O0 %s -o %t 2>&1
// RUN: %run %t 2>&1 | FileCheck %s
// FIXME: Re-enable once PR33590 is fixed.
// UNSUPPORTED: x86_64
#include <sanitizer/esan_interface.h>
#include <sched.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
const int size = 0x1 << 25; // 523288 cache lines
int main(int argc, char **argv) {
char *buf = (char *)mmap(0, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
// To avoid flakiness stemming from whether the sideline thread
// is scheduled enough on a loaded test machine, we coordinate
// with esan itself:
if (__esan_get_sample_count) {
while (__esan_get_sample_count() < 4) {
for (int i = 0; i < size; ++i)
buf[i] = i;
sched_yield();
}
}
munmap(buf, size);
// We only check for a few samples here to reduce the chance of flakiness.
// CHECK: =={{[0-9]+}}== Total number of samples: {{[0-9]+}}
// CHECK-NEXT: =={{[0-9]+}}== Samples array #0 at period 20 ms
// CHECK-NEXT: =={{[0-9]+}}==# 0: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK-NEXT: =={{[0-9]+}}==# 1: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK-NEXT: =={{[0-9]+}}==# 2: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK-NEXT: =={{[0-9]+}}==# 3: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK: =={{[0-9]+}}== Samples array #1 at period 80 ms
// CHECK-NEXT: =={{[0-9]+}}==# 0: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
// CHECK: =={{[0-9]+}}== Samples array #2 at period 320 ms
// CHECK: =={{[0-9]+}}== Samples array #3 at period 1280 ms
// CHECK: =={{[0-9]+}}== Samples array #4 at period 5120 ms
// CHECK: =={{[0-9]+}}== Samples array #5 at period 20 sec
// CHECK: =={{[0-9]+}}== Samples array #6 at period 81 sec
// CHECK: =={{[0-9]+}}== Samples array #7 at period 327 sec
// CHECK: {{.*}} EfficiencySanitizer: the total working set size: 32 MB (5242{{[0-9][0-9]}} cache lines)
return 0;
}

View File

@@ -0,0 +1,75 @@
// RUN: %clang_esan_wset -O0 %s -o %t 2>&1
// RUN: %run %t 2>&1 | FileCheck %s
#include <assert.h>
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
sigjmp_buf mark;
static void SignalHandler(int Sig) {
if (Sig == SIGSEGV) {
fprintf(stderr, "Handling SIGSEGV for signal\n");
siglongjmp(mark, 1);
}
exit(1);
}
static void SigactionHandler(int Sig, siginfo_t *Info, void *Ctx) {
if (Sig == SIGSEGV) {
fprintf(stderr, "Handling SIGSEGV for sigaction\n");
siglongjmp(mark, 1);
}
exit(1);
}
int main(int argc, char **argv) {
__sighandler_t Prior = signal(SIGSEGV, SignalHandler);
assert(Prior == SIG_DFL);
if (sigsetjmp(mark, 1) == 0)
*((volatile int *)(ssize_t)argc) = 42; // Raise SIGSEGV
fprintf(stderr, "Past longjmp for signal\n");
Prior = signal(SIGSEGV, SIG_DFL);
assert(Prior == SignalHandler);
struct sigaction SigAct;
SigAct.sa_sigaction = SigactionHandler;
int Res = sigfillset(&SigAct.sa_mask);
assert(Res == 0);
SigAct.sa_flags = SA_SIGINFO;
Res = sigaction(SIGSEGV, &SigAct, NULL);
assert(Res == 0);
if (sigsetjmp(mark, 1) == 0)
*((volatile int *)(ssize_t)argc) = 42; // Raise SIGSEGV
fprintf(stderr, "Past longjmp for sigaction\n");
Res = sigaction(SIGSEGV, NULL, &SigAct);
assert(Res == 0);
assert(SigAct.sa_sigaction == SigactionHandler);
// Test blocking SIGSEGV and raising a shadow fault.
sigset_t Set;
sigemptyset(&Set);
sigaddset(&Set, SIGSEGV);
Res = sigprocmask(SIG_BLOCK, &Set, NULL);
// Make a large enough mapping that its start point will be before any
// prior library-region shadow access.
char *buf = (char *)mmap(0, 640*1024, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
buf[0] = 4;
munmap(buf, 640*1024);
fprintf(stderr, "Past blocked-SIGSEGV shadow fault\n");
return 0;
}
// CHECK: Handling SIGSEGV for signal
// CHECK-NEXT: Past longjmp for signal
// CHECK-NEXT: Handling SIGSEGV for sigaction
// CHECK-NEXT: Past longjmp for sigaction
// CHECK-NEXT: Past blocked-SIGSEGV shadow fault
// CHECK: {{.*}} EfficiencySanitizer: the total working set size: {{[0-9]+}} Bytes ({{[0-9][0-9]}} cache lines)

View File

@@ -0,0 +1,33 @@
// RUN: %clang_esan_wset -O0 %s -o %t 2>&1
// RUN: %run %t 2>&1 | FileCheck %s
// FIXME: Re-enable once PR33590 is fixed.
// UNSUPPORTED: x86_64
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <assert.h>
const int size = 0x1 << 25; // 523288 cache lines
const int line_size = 64;
int main(int argc, char **argv) {
char *bufA = (char *)malloc(sizeof(char) * line_size);
char bufB[64];
char *bufC = (char *)mmap(0, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
bufA[0] = 0;
// This additional access to the same line should not increase the line
// count: but it's difficult to make a non-flaky test that measures the
// lines down to the ones digit so right now we're not really testing that.
// If we add a heap-only mode we may be able to be more precise.
bufA[1] = 0;
bufB[33] = 1;
for (int i = 0; i < size; i += line_size)
bufC[i] = 0;
free(bufA);
munmap(bufC, 0x4000);
// CHECK: {{.*}} EfficiencySanitizer: the total working set size: 32 MB (524{{[0-9][0-9][0-9]}} cache lines)
return 0;
}