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 23static 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(SK_BUILD_FOR_AFL_FUZZ) 27 exit(1); 28#else 29 abort(); 30#endif 31} 32 33static 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 41void 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 55void sk_out_of_memory(void) { 56 SkDEBUGFAIL("sk_out_of_memory"); 57#if defined(SK_BUILD_FOR_AFL_FUZZ) 58 exit(1); 59#else 60 abort(); 61#endif 62} 63 64void* sk_realloc_throw(void* addr, size_t size) { 65 return throw_on_failure(size, realloc(addr, size)); 66} 67 68void sk_free(void* p) { 69 if (p) { 70 free(p); 71 } 72} 73 74void* 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#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && defined(__BIONIC__) 80 /* TODO: After b/169449588 is fixed, we will want to change this to restore 81 * original behavior instead of always disabling the flag. 82 * TODO: After b/158870657 is fixed and scudo is used globally, we can assert when an 83 * an error is returned. 84 */ 85 // malloc() generally doesn't initialize its memory and that's a huge security hole, 86 // so Android has replaced its malloc() with one that zeros memory, 87 // but that's a huge performance hit for HWUI, so turn it back off again. 88 (void)mallopt(M_THREAD_DISABLE_MEM_INIT, 1); 89#endif 90 p = malloc(size); 91#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && defined(__BIONIC__) 92 (void)mallopt(M_THREAD_DISABLE_MEM_INIT, 0); 93#endif 94 } 95 if (flags & SK_MALLOC_THROW) { 96 return throw_on_failure(size, p); 97 } else { 98 return p; 99 } 100} 101