system_utils.h (8043B)
1 // 2 // Copyright 2014 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // system_utils.h: declaration of OS-specific utility functions 8 9 #ifndef COMMON_SYSTEM_UTILS_H_ 10 #define COMMON_SYSTEM_UTILS_H_ 11 12 #include "common/Optional.h" 13 #include "common/angleutils.h" 14 15 #include <functional> 16 #include <string> 17 #include <string_view> 18 19 namespace angle 20 { 21 std::string GetExecutableName(); 22 std::string GetExecutablePath(); 23 std::string GetExecutableDirectory(); 24 std::string GetModuleDirectory(); 25 const char *GetSharedLibraryExtension(); 26 const char *GetExecutableExtension(); 27 char GetPathSeparator(); 28 Optional<std::string> GetCWD(); 29 bool SetCWD(const char *dirName); 30 bool SetEnvironmentVar(const char *variableName, const char *value); 31 bool UnsetEnvironmentVar(const char *variableName); 32 bool GetBoolEnvironmentVar(const char *variableName); 33 std::string GetEnvironmentVar(const char *variableName); 34 std::string GetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName, 35 const char *propertyName); 36 std::string GetAndSetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName, 37 const char *propertyName); 38 std::string GetEnvironmentVarOrAndroidProperty(const char *variableName, const char *propertyName); 39 const char *GetPathSeparatorForEnvironmentVar(); 40 bool PrependPathToEnvironmentVar(const char *variableName, const char *path); 41 bool IsDirectory(const char *filename); 42 bool IsFullPath(std::string dirName); 43 std::string GetRootDirectory(); 44 std::string ConcatenatePath(std::string first, std::string second); 45 46 Optional<std::string> GetTempDirectory(); 47 Optional<std::string> CreateTemporaryFileInDirectory(const std::string &directory); 48 Optional<std::string> CreateTemporaryFile(); 49 50 // Get absolute time in seconds. Use this function to get an absolute time with an unknown origin. 51 double GetCurrentSystemTime(); 52 // Get CPU time for current process in seconds. 53 double GetCurrentProcessCpuTime(); 54 55 // Unique thread id (std::this_thread::get_id() gets recycled!) 56 uint64_t GetCurrentThreadUniqueId(); 57 58 // Run an application and get the output. Gets a nullptr-terminated set of args to execute the 59 // application with, and returns the stdout and stderr outputs as well as the exit code. 60 // 61 // Pass nullptr for stdoutOut/stderrOut if you don't need to capture. exitCodeOut is required. 62 // 63 // Returns false if it fails to actually execute the application. 64 bool RunApp(const std::vector<const char *> &args, 65 std::string *stdoutOut, 66 std::string *stderrOut, 67 int *exitCodeOut); 68 69 // Use SYSTEM_DIR to bypass loading ANGLE libraries with the same name as system DLLS 70 // (e.g. opengl32.dll) 71 enum class SearchType 72 { 73 // Try to find the library in the same directory as the current module 74 ModuleDir, 75 // Load the library from the system directories 76 SystemDir, 77 // Get a reference to an already loaded shared library. 78 AlreadyLoaded, 79 }; 80 81 void *OpenSystemLibrary(const char *libraryName, SearchType searchType); 82 void *OpenSystemLibraryWithExtension(const char *libraryName, SearchType searchType); 83 void *OpenSystemLibraryAndGetError(const char *libraryName, 84 SearchType searchType, 85 std::string *errorOut); 86 void *OpenSystemLibraryWithExtensionAndGetError(const char *libraryName, 87 SearchType searchType, 88 std::string *errorOut); 89 90 void *GetLibrarySymbol(void *libraryHandle, const char *symbolName); 91 std::string GetLibraryPath(void *libraryHandle); 92 void CloseSystemLibrary(void *libraryHandle); 93 94 class Library : angle::NonCopyable 95 { 96 public: 97 Library() {} 98 Library(void *libraryHandle) : mLibraryHandle(libraryHandle) {} 99 ~Library() { close(); } 100 101 [[nodiscard]] bool open(const char *libraryName, SearchType searchType) 102 { 103 close(); 104 mLibraryHandle = OpenSystemLibrary(libraryName, searchType); 105 return mLibraryHandle != nullptr; 106 } 107 108 [[nodiscard]] bool openWithExtension(const char *libraryName, SearchType searchType) 109 { 110 close(); 111 mLibraryHandle = OpenSystemLibraryWithExtension(libraryName, searchType); 112 return mLibraryHandle != nullptr; 113 } 114 115 [[nodiscard]] bool openAndGetError(const char *libraryName, 116 SearchType searchType, 117 std::string *errorOut) 118 { 119 close(); 120 mLibraryHandle = OpenSystemLibraryAndGetError(libraryName, searchType, errorOut); 121 return mLibraryHandle != nullptr; 122 } 123 124 [[nodiscard]] bool openWithExtensionAndGetError(const char *libraryName, 125 SearchType searchType, 126 std::string *errorOut) 127 { 128 close(); 129 mLibraryHandle = 130 OpenSystemLibraryWithExtensionAndGetError(libraryName, searchType, errorOut); 131 return mLibraryHandle != nullptr; 132 } 133 134 void close() 135 { 136 if (mLibraryHandle) 137 { 138 CloseSystemLibrary(mLibraryHandle); 139 mLibraryHandle = nullptr; 140 } 141 } 142 143 void *getSymbol(const char *symbolName) { return GetLibrarySymbol(mLibraryHandle, symbolName); } 144 145 void *getNative() const { return mLibraryHandle; } 146 147 std::string getPath() const { return GetLibraryPath(mLibraryHandle); } 148 149 template <typename FuncT> 150 void getAs(const char *symbolName, FuncT *funcOut) 151 { 152 *funcOut = reinterpret_cast<FuncT>(getSymbol(symbolName)); 153 } 154 155 private: 156 void *mLibraryHandle = nullptr; 157 }; 158 159 Library *OpenSharedLibrary(const char *libraryName, SearchType searchType); 160 Library *OpenSharedLibraryWithExtension(const char *libraryName, SearchType searchType); 161 Library *OpenSharedLibraryAndGetError(const char *libraryName, 162 SearchType searchType, 163 std::string *errorOut); 164 Library *OpenSharedLibraryWithExtensionAndGetError(const char *libraryName, 165 SearchType searchType, 166 std::string *errorOut); 167 168 // Returns true if the process is currently being debugged. 169 bool IsDebuggerAttached(); 170 171 // Calls system APIs to break into the debugger. 172 void BreakDebugger(); 173 174 uint64_t GetProcessMemoryUsageKB(); 175 176 bool ProtectMemory(uintptr_t start, size_t size); 177 bool UnprotectMemory(uintptr_t start, size_t size); 178 179 size_t GetPageSize(); 180 181 // Return type of the PageFaultCallback 182 enum class PageFaultHandlerRangeType 183 { 184 // The memory address was known by the page fault handler 185 InRange, 186 // The memory address was not in the page fault handler's range 187 // and the signal will be forwarded to the default page handler. 188 OutOfRange, 189 }; 190 191 using PageFaultCallback = std::function<PageFaultHandlerRangeType(uintptr_t)>; 192 193 class PageFaultHandler : angle::NonCopyable 194 { 195 public: 196 PageFaultHandler(PageFaultCallback callback); 197 virtual ~PageFaultHandler(); 198 199 // Registers OS level page fault handler for memory protection signals 200 // and enables reception on PageFaultCallback 201 virtual bool enable() = 0; 202 203 // Unregisters OS level page fault handler and deactivates PageFaultCallback 204 virtual bool disable() = 0; 205 206 protected: 207 PageFaultCallback mCallback; 208 }; 209 210 // Creates single instance page fault handler 211 PageFaultHandler *CreatePageFaultHandler(PageFaultCallback callback); 212 213 #ifdef ANGLE_PLATFORM_WINDOWS 214 // Convert an UTF-16 wstring to an UTF-8 string. 215 std::string Narrow(const std::wstring_view &utf16); 216 217 // Convert an UTF-8 string to an UTF-16 wstring. 218 std::wstring Widen(const std::string_view &utf8); 219 #endif 220 221 std::string StripFilenameFromPath(const std::string &path); 222 } // namespace angle 223 224 #endif // COMMON_SYSTEM_UTILS_H_