0bd833fad4d57a48d52f7bdfafae8e0e767be56e
[WebKit-https.git] / Source / bmalloc / bmalloc / Environment.cpp
1 /*
2  * Copyright (C) 2014 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "BPlatform.h"
27 #include "Environment.h"
28 #include <cstdlib>
29 #include <cstring>
30 #if BOS(DARWIN)
31 #include <mach-o/dyld.h>
32 #elif BOS(UNIX)
33 #include <dlfcn.h>
34 #endif
35
36 namespace bmalloc {
37
38 static bool isMallocEnvironmentVariableSet()
39 {
40     const char* list[] = {
41         "Malloc",
42         "MallocLogFile",
43         "MallocGuardEdges",
44         "MallocDoNotProtectPrelude",
45         "MallocDoNotProtectPostlude",
46         "MallocStackLogging",
47         "MallocStackLoggingNoCompact",
48         "MallocStackLoggingDirectory",
49         "MallocScribble",
50         "MallocCheckHeapStart",
51         "MallocCheckHeapEach",
52         "MallocCheckHeapSleep",
53         "MallocCheckHeapAbort",
54         "MallocErrorAbort",
55         "MallocCorruptionAbort",
56         "MallocHelp"
57     };
58     size_t size = sizeof(list) / sizeof(const char*);
59     
60     for (size_t i = 0; i < size; ++i) {
61         if (getenv(list[i]))
62             return true;
63     }
64
65     return false;
66 }
67
68 static bool isLibgmallocEnabled()
69 {
70     char* variable = getenv("DYLD_INSERT_LIBRARIES");
71     if (!variable)
72         return false;
73     if (!strstr(variable, "libgmalloc"))
74         return false;
75     return true;
76 }
77
78 static bool isSanitizerEnabled()
79 {
80 #if BOS(DARWIN)
81     static const char sanitizerPrefix[] = "/libclang_rt.";
82     static const char asanName[] = "asan_";
83     static const char tsanName[] = "tsan_";
84     uint32_t imageCount = _dyld_image_count();
85     for (uint32_t i = 0; i < imageCount; ++i) {
86         const char* imageName = _dyld_get_image_name(i);
87         if (!imageName)
88             continue;
89         if (const char* s = strstr(imageName, sanitizerPrefix)) {
90             const char* sanitizerName = s + sizeof(sanitizerPrefix) - 1;
91             if (!strncmp(sanitizerName, asanName, sizeof(asanName) - 1))
92                 return true;
93             if (!strncmp(sanitizerName, tsanName, sizeof(tsanName) - 1))
94                 return true;
95         }
96     }
97     return false;
98 #elif BOS(UNIX)
99     void* handle = dlopen(nullptr, RTLD_NOW);
100     if (!handle)
101         return false;
102     bool result = !!dlsym(handle, "__asan_init") || !!dlsym(handle, "__tsan_init");
103     dlclose(handle);
104     return result;
105 #else
106     return false;
107 #endif
108 }
109
110 Environment::Environment(std::lock_guard<Mutex>&)
111     : m_isDebugHeapEnabled(computeIsDebugHeapEnabled())
112 {
113 }
114
115 bool Environment::computeIsDebugHeapEnabled()
116 {
117     if (isMallocEnvironmentVariableSet())
118         return true;
119     if (isLibgmallocEnabled())
120         return true;
121     if (isSanitizerEnabled())
122         return true;
123     return false;
124 }
125
126 } // namespace bmalloc