• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
main(int argc,char ** argv)20 int main(int argc, char **argv) {
21   assert(argc == 2);
22 
23   if (!strcmp(argv[1], "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(argv[1], "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);
37       assert(p);
38       assert(__sanitizer_get_ownership(p));
39       assert(__sanitizer_get_allocated_size(p) >= size);
40       free(p);
41     }
42   }
43   if (!strcmp(argv[1], "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(argv[1], "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);
54       memset(p, 0, size);
55       pointers.push_back(p);
56     }
57     // Set the soft RSS limit to 1Mb.
58     __scudo_set_rss_limit(1, 0);
59     usleep(20000);
60     // The following allocation should return NULL.
61     void *p = malloc(size);
62     assert(!p);
63     // Remove the soft RSS limit.
64     __scudo_set_rss_limit(0, 0);
65     // The following allocation should succeed.
66     p = malloc(size);
67     assert(p);
68     free(p);
69     while (!pointers.empty()) {
70       free(pointers.back());
71       pointers.pop_back();
72     }
73   }
74   if (!strcmp(argv[1], "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);
80       memset(p, 0, size);
81       pointers.push_back(p);
82     }
83     // Set the hard RSS limit to 1Mb
84     __scudo_set_rss_limit(1, 1);
85     usleep(20000);
86     // The following should trigger our death.
87     void *p = malloc(size);
88   }
89 
90   return 0;
91 }
92