Changeset View
Changeset View
Standalone View
Standalone View
test/scudo/interface.cpp
// RUN: %clangxx_scudo %s -lstdc++ -o %t | // RUN: %clangxx_scudo %s -lstdc++ -o %t | ||||
// RUN: %run %t ownership 2>&1 | // RUN: %run %t ownership 2>&1 | ||||
// RUN: %run %t ownership-and-size 2>&1 | // RUN: %run %t ownership-and-size 2>&1 | ||||
// RUN: %run %t heap-size 2>&1 | // RUN: %run %t heap-size 2>&1 | ||||
// RUN: %env_scudo_opts="allocator_may_return_null=1" %run %t soft-limit 2>&1 | // RUN: %env_scudo_opts="allocator_may_return_null=1" %run %t soft-limit 2>&1 | ||||
// RUN: %env_scudo_opts="allocator_may_return_null=1" not %run %t hard-limit 2>&1 | // RUN: %env_scudo_opts="allocator_may_return_null=1" not %run %t hard-limit 2>&1 | ||||
// Tests that the sanitizer interface functions behave appropriately. | // Tests that the sanitizer interface functions behave appropriately. | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <assert.h> | #include <assert.h> | ||||
#include <string.h> | #include <string.h> | ||||
#if defined(_WIN32) | |||||
# include <windows.h> | |||||
#else | |||||
#include <unistd.h> | # include <unistd.h> | ||||
#endif | |||||
#include <vector> | #include <vector> | ||||
#include <sanitizer/allocator_interface.h> | #include <sanitizer/allocator_interface.h> | ||||
#include <sanitizer/scudo_interface.h> | #include <sanitizer/scudo_interface.h> | ||||
#if defined(_MSC_VER) | |||||
#include <BaseTsd.h> | |||||
typedef SSIZE_T ssize_t; | |||||
#endif | |||||
void sleep_ms(unsigned int ms) { | |||||
#if defined(_WIN32) | |||||
Sleep(ms); | |||||
#else | |||||
usleep(ms * 1000U); | |||||
#endif | |||||
} | |||||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||||
{ | { | ||||
assert(argc == 2); | assert(argc == 2); | ||||
if (!strcmp(argv[1], "ownership")) { | if (!strcmp(argv[1], "ownership")) { | ||||
// Ensures that __sanitizer_get_ownership can be called before any other | // Ensures that __sanitizer_get_ownership can be called before any other | ||||
// allocator function, and that it behaves properly on a pointer not owned | // allocator function, and that it behaves properly on a pointer not owned | ||||
// by us. | // by us. | ||||
Show All 24 Lines | if (!strcmp(argv[1], "soft-limit")) { | ||||
size_t size = 1 << 19; // 512Kb | size_t size = 1 << 19; // 512Kb | ||||
for (int i = 0; i < 5; i++) { | for (int i = 0; i < 5; i++) { | ||||
void *p = malloc(size); | void *p = malloc(size); | ||||
memset(p, 0, size); | memset(p, 0, size); | ||||
pointers.push_back(p); | pointers.push_back(p); | ||||
} | } | ||||
// Set the soft RSS limit to 1Mb. | // Set the soft RSS limit to 1Mb. | ||||
__scudo_set_rss_limit(1, 0); | __scudo_set_rss_limit(1, 0); | ||||
usleep(20000); | sleep_ms(200); | ||||
// The following allocation should return NULL. | // The following allocation should return NULL. | ||||
void *p = malloc(size); | void *p = malloc(size); | ||||
assert(!p); | assert(!p); | ||||
// Remove the soft RSS limit. | // Remove the soft RSS limit. | ||||
__scudo_set_rss_limit(0, 0); | __scudo_set_rss_limit(0, 0); | ||||
// The following allocation should succeed. | // The following allocation should succeed. | ||||
p = malloc(size); | p = malloc(size); | ||||
assert(p); | assert(p); | ||||
Show All 9 Lines | if (!strcmp(argv[1], "hard-limit")) { | ||||
size_t size = 1 << 19; // 512Kb | size_t size = 1 << 19; // 512Kb | ||||
for (int i = 0; i < 5; i++) { | for (int i = 0; i < 5; i++) { | ||||
void *p = malloc(size); | void *p = malloc(size); | ||||
memset(p, 0, size); | memset(p, 0, size); | ||||
pointers.push_back(p); | pointers.push_back(p); | ||||
} | } | ||||
// Set the hard RSS limit to 1Mb | // Set the hard RSS limit to 1Mb | ||||
__scudo_set_rss_limit(1, 1); | __scudo_set_rss_limit(1, 1); | ||||
usleep(20000); | sleep_ms(200); | ||||
// The following should trigger our death. | // The following should trigger our death. | ||||
void *p = malloc(size); | void *p = malloc(size); | ||||
} | } | ||||
return 0; | return 0; | ||||
} | } |