1 | /* |
2 | * Copyright 2011 Google Inc. |
3 | * |
4 | * Use of this source code is governed by a BSD-style license that can be |
5 | * found in the LICENSE file. |
6 | */ |
7 | |
8 | #include "include/private/SkMalloc.h" |
9 | |
10 | #include <cstdlib> |
11 | |
12 | #if defined(SK_DEBUG) && defined(SK_BUILD_FOR_WIN) |
13 | #include <intrin.h> |
14 | // This is a super stable value and setting it here avoids pulling in all of windows.h. |
15 | #ifndef FAST_FAIL_FATAL_APP_EXIT |
16 | #define FAST_FAIL_FATAL_APP_EXIT 7 |
17 | #endif |
18 | #endif |
19 | |
20 | #define SK_DEBUGFAILF(fmt, ...) \ |
21 | SkASSERT((SkDebugf(fmt"\n", __VA_ARGS__), false)) |
22 | |
23 | static inline void sk_out_of_memory(size_t size) { |
24 | SK_DEBUGFAILF("sk_out_of_memory (asked for %zu bytes)" , |
25 | size); |
26 | #if defined(IS_FUZZING_WITH_AFL) |
27 | exit(1); |
28 | #else |
29 | abort(); |
30 | #endif |
31 | } |
32 | |
33 | static inline void* throw_on_failure(size_t size, void* p) { |
34 | if (size > 0 && p == nullptr) { |
35 | // If we've got a nullptr here, the only reason we should have failed is running out of RAM. |
36 | sk_out_of_memory(size); |
37 | } |
38 | return p; |
39 | } |
40 | |
41 | void sk_abort_no_print() { |
42 | #if defined(SK_BUILD_FOR_WIN) && defined(SK_IS_BOT) |
43 | // do not display a system dialog before aborting the process |
44 | _set_abort_behavior(0, _WRITE_ABORT_MSG); |
45 | #endif |
46 | #if defined(SK_DEBUG) && defined(SK_BUILD_FOR_WIN) |
47 | __fastfail(FAST_FAIL_FATAL_APP_EXIT); |
48 | #elif defined(__clang__) |
49 | __builtin_trap(); |
50 | #else |
51 | abort(); |
52 | #endif |
53 | } |
54 | |
55 | void sk_out_of_memory(void) { |
56 | SkDEBUGFAIL("sk_out_of_memory" ); |
57 | #if defined(IS_FUZZING_WITH_AFL) |
58 | exit(1); |
59 | #else |
60 | abort(); |
61 | #endif |
62 | } |
63 | |
64 | void* sk_realloc_throw(void* addr, size_t size) { |
65 | return throw_on_failure(size, realloc(addr, size)); |
66 | } |
67 | |
68 | void sk_free(void* p) { |
69 | if (p) { |
70 | free(p); |
71 | } |
72 | } |
73 | |
74 | void* sk_malloc_flags(size_t size, unsigned flags) { |
75 | void* p; |
76 | if (flags & SK_MALLOC_ZERO_INITIALIZE) { |
77 | p = calloc(size, 1); |
78 | } else { |
79 | p = malloc(size); |
80 | } |
81 | if (flags & SK_MALLOC_THROW) { |
82 | return throw_on_failure(size, p); |
83 | } else { |
84 | return p; |
85 | } |
86 | } |
87 | |