1// RUN: %clangxx_scudo %s -lstdc++ -o %t
2// RUN: %run %t ownership 2>&1
3// RUN: %run %t ownership-and-size 2>&1
4// RUN: %run %t heap-size 2>&1
5// RUN: %env_scudo_opts="allocator_may_return_null=1" %run %t soft-limit 2>&1
6// RUN: %env_scudo_opts="allocator_may_return_null=1" not %run %t hard-limit 2>&1
7
8// Tests that the sanitizer interface functions behave appropriately.
9
10#include <assert.h>
11#include <stdlib.h>
12#include <string.h>
13#include <unistd.h>
14
15#include <vector>
16
17#include <sanitizer/allocator_interface.h>
18#include <sanitizer/scudo_interface.h>
19
20int main(int argc, char **argv) {
21 assert(argc == 2);
22
23 if (!strcmp(s1: argv[1], s2: "ownership")) {
24 // Ensures that __sanitizer_get_ownership can be called before any other
25 // allocator function, and that it behaves properly on a pointer not owned
26 // by us.
27 assert(!__sanitizer_get_ownership(argv));
28 }
29 if (!strcmp(s1: argv[1], s2: "ownership-and-size")) {
30 // Tests that __sanitizer_get_ownership and __sanitizer_get_allocated_size
31 // behave properly on chunks allocated by the Primary and Secondary.
32 void *p;
33 std::vector<ssize_t> sizes{1, 8, 16, 32, 1024, 32768,
34 1 << 16, 1 << 17, 1 << 20, 1 << 24};
35 for (size_t size : sizes) {
36 p = malloc(size: size);
37 assert(p);
38 assert(__sanitizer_get_ownership(p));
39 assert(__sanitizer_get_allocated_size(p) >= size);
40 free(ptr: p);
41 }
42 }
43 if (!strcmp(s1: argv[1], s2: "heap-size")) {
44 // Ensures that __sanitizer_get_heap_size can be called before any other
45 // allocator function.
46 assert(__sanitizer_get_heap_size() >= 0);
47 }
48 if (!strcmp(s1: argv[1], s2: "soft-limit")) {
49 // Verifies that setting the soft RSS limit at runtime works as expected.
50 std::vector<void *> pointers;
51 size_t size = 1 << 19; // 512Kb
52 for (int i = 0; i < 5; i++) {
53 void *p = malloc(size: size);
54 memset(s: p, c: 0, n: size);
55 pointers.push_back(x: p);
56 }
57 // Set the soft RSS limit to 1Mb.
58 __scudo_set_rss_limit(LimitMb: 1, HardLimit: 0);
59 usleep(useconds: 20000);
60 // The following allocation should return NULL.
61 void *p = malloc(size: size);
62 assert(!p);
63 // Remove the soft RSS limit.
64 __scudo_set_rss_limit(LimitMb: 0, HardLimit: 0);
65 // The following allocation should succeed.
66 p = malloc(size: size);
67 assert(p);
68 free(ptr: p);
69 while (!pointers.empty()) {
70 free(ptr: pointers.back());
71 pointers.pop_back();
72 }
73 }
74 if (!strcmp(s1: argv[1], s2: "hard-limit")) {
75 // Verifies that setting the hard RSS limit at runtime works as expected.
76 std::vector<void *> pointers;
77 size_t size = 1 << 19; // 512Kb
78 for (int i = 0; i < 5; i++) {
79 void *p = malloc(size: size);
80 memset(s: p, c: 0, n: size);
81 pointers.push_back(x: p);
82 }
83 // Set the hard RSS limit to 1Mb
84 __scudo_set_rss_limit(LimitMb: 1, HardLimit: 1);
85 usleep(useconds: 20000);
86 // The following should trigger our death.
87 void *p = malloc(size: size);
88 }
89
90 return 0;
91}
92

source code of compiler-rt/test/scudo/interface.cpp