1// Test the behavior of malloc/calloc/realloc when the allocation causes OOM
2// in the secondary allocator.
3// By default (allocator_may_return_null=0) the process should crash.
4// With allocator_may_return_null=1 the allocator should return 0.
5// Set the limit to 20.5T on 64 bits to account for ASan shadow memory,
6// allocator buffers etc. so that the test allocation of ~1T will trigger OOM.
7// Limit this test to Linux since we're relying on allocator internal
8// limits (shadow memory size, allocation limits etc.)
9
10// RUN: %clangxx_asan -O0 %s -o %t
11// RUN: ulimit -v 22024290304
12// RUN: not %run %t malloc 2>&1 \
13// RUN: | FileCheck %s --check-prefixes=CHECK-MALLOC,CHECK-CRASH
14// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \
15// RUN: | FileCheck %s --check-prefixes=CHECK-MALLOC,CHECK-CRASH
16// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t malloc 2>&1 \
17// RUN: | FileCheck %s --check-prefixes=CHECK-MALLOC,CHECK-NULL
18// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \
19// RUN: | FileCheck %s --check-prefixes=CHECK-CALLOC,CHECK-CRASH
20// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t calloc 2>&1 \
21// RUN: | FileCheck %s --check-prefixes=CHECK-CALLOC,CHECK-NULL
22// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \
23// RUN: | FileCheck %s --check-prefixes=CHECK-REALLOC,CHECK-CRASH
24// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t realloc 2>&1 \
25// RUN: | FileCheck %s --check-prefixes=CHECK-REALLOC,CHECK-NULL
26// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \
27// RUN: | FileCheck %s --check-prefixes=CHECK-MALLOC-REALLOC,CHECK-CRASH
28// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \
29// RUN: | FileCheck %s --check-prefixes=CHECK-MALLOC-REALLOC,CHECK-NULL
30
31// ASan shadow memory on s390 is too large for this test.
32// AArch64 bots fail on this test.
33// TODO(alekseys): Android lit do not run ulimit on device.
34// REQUIRES: shadow-scale-3
35// UNSUPPORTED: android, target={{(s390|aarch64|powerpc64le).*}}
36
37#include <stdlib.h>
38#include <string.h>
39#include <stdio.h>
40#include <assert.h>
41
42int main(int argc, char **argv) {
43 assert(argc == 2);
44 const char *action = argv[1];
45 fprintf(stderr, format: "%s:\n", action);
46
47 // Allocate just a bit less than max allocation size enforced by ASan's
48 // allocator (currently 1T and 3G).
49 const size_t size =
50#if __LP64__
51 (1ULL << 40) - (1ULL << 30);
52#else
53 (3ULL << 30) - (1ULL << 20);
54#endif
55
56 void *x = 0;
57
58 if (!strcmp(s1: action, s2: "malloc")) {
59 x = malloc(size: size);
60 } else if (!strcmp(s1: action, s2: "calloc")) {
61 x = calloc(nmemb: size / 4, size: 4);
62 } else if (!strcmp(s1: action, s2: "realloc")) {
63 x = realloc(ptr: 0, size: size);
64 } else if (!strcmp(s1: action, s2: "realloc-after-malloc")) {
65 char *t = (char*)malloc(size: 100);
66 *t = 42;
67 x = realloc(ptr: t, size: size);
68 assert(*t == 42);
69 free(ptr: t);
70 } else {
71 assert(0);
72 }
73
74 // The NULL pointer is printed differently on different systems, while (long)0
75 // is always the same.
76 fprintf(stderr, format: "x: %lx\n", (long)x);
77 free(ptr: x);
78
79 return x != 0;
80}
81
82// CHECK-MALLOC: malloc:
83// CHECK-CALLOC: calloc:
84// CHECK-REALLOC: realloc:
85// CHECK-MALLOC-REALLOC: realloc-after-malloc:
86
87// CHECK-CRASH: SUMMARY: AddressSanitizer: out-of-memory
88// CHECK-NULL: x: 0
89

source code of compiler-rt/test/asan/TestCases/Linux/allocator_oom_test.cpp