Make Disabling Dynamic Library unloading a runtime option
authorCharles Giessen <charles@lunarg.com>
Thu, 27 Jul 2023 20:10:06 +0000 (14:10 -0600)
committerJuan Ramos <114601453+juan-lunarg@users.noreply.github.com>
Thu, 27 Jul 2023 21:57:37 +0000 (15:57 -0600)
This behavior was previously only available if compiled with a specific
option, but its useful enough to be moved into a runtime option.

To enable the behavior, set the environment variable
VK_LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING to "1".

BUILD.md
docs/LoaderInterfaceArchitecture.md
loader/CMakeLists.txt
loader/loader.c
loader/vk_loader_platform.h

index c8cbd9c..1c2f0c9 100644 (file)
--- a/BUILD.md
+++ b/BUILD.md
@@ -221,23 +221,22 @@ When generating build files through CMake, several options can be specified to
 customize the build.
 The following is a table of all on/off options currently supported by this repository:
 
-| Option                                   | Platform      | Default | Description                                                                                                                                                                       |
-| ---------------------------------------- | ------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| BUILD_TESTS                              | All           | `OFF`   | Controls whether or not the loader tests are built.                                                                                                                               |
-| BUILD_WSI_XCB_SUPPORT                    | Linux         | `ON`    | Build the loader with the XCB entry points enabled. Without this, the XCB headers should not be needed, but the extension `VK_KHR_xcb_surface` won't be available.                |
-| BUILD_WSI_XLIB_SUPPORT                   | Linux         | `ON`    | Build the loader with the Xlib entry points enabled. Without this, the X11 headers should not be needed, but the extension `VK_KHR_xlib_surface` won't be available.              |
-| BUILD_WSI_WAYLAND_SUPPORT                | Linux         | `ON`    | Build the loader with the Wayland entry points enabled. Without this, the Wayland headers should not be needed, but the extension `VK_KHR_wayland_surface` won't be available.    |
-| BUILD_WSI_DIRECTFB_SUPPORT               | Linux         | `OFF`   | Build the loader with the DirectFB entry points enabled. Without this, the DirectFB headers should not be needed, but the extension `VK_EXT_directfb_surface` won't be available. |
-| BUILD_WSI_SCREEN_QNX_SUPPORT             | QNX           | `OFF`   | Build the loader with the QNX Screen entry points enabled. Without this the extension `VK_QNX_screen_surface` won't be available.                                                 |
-| ENABLE_WIN10_ONECORE                     | Windows       | `OFF`   | Link the loader to the [OneCore](https://msdn.microsoft.com/en-us/library/windows/desktop/mt654039.aspx) umbrella library, instead of the standard Win32 ones.                    |
-| USE_GAS                                  | Linux         | `ON`    | Controls whether to build assembly files with the GNU assembler, else fallback to C code.                                                                                         |
-| USE_MASM                                 | Windows       | `ON`    | Controls whether to build assembly files with MS assembler, else fallback to C code                                                                                               |
-| BUILD_STATIC_LOADER                      | macOS         | `OFF`   | This allows the loader to be built as a static library on macOS. Not tested, use at your own risk.                                                                                |
-| LOADER_ENABLE_ADDRESS_SANITIZER          | Linux & macOS | `OFF`   | Enables Address Sanitizer in the loader and tests.                                                                                                                                |
-| LOADER_ENABLE_THREAD_SANITIZER           | Linux & macOS | `OFF`   | Enables Thread Sanitizer in the loader and tests.                                                                                                                                 |
-| LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING | All           | `OFF`   | Causes the loader to not unload dynamic libraries. Example use case. This option allows leak sanitizers to have full stack traces.                                                |
-| LOADER_USE_UNSAFE_FILE_SEARCH            | All           | `OFF`   | Disables security policies that prevent unsecure locations from being used when running with elevated permissions.                                                                |
-| LOADER_CODEGEN                           | All           | `OFF`   | Creates a helper CMake target to generate code.                                                                                                                                   |
+| Option                          | Platform      | Default | Description                                                                                                                                                                       |
+| ------------------------------- | ------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| BUILD_TESTS                     | All           | `OFF`   | Controls whether or not the loader tests are built.                                                                                                                               |
+| BUILD_WSI_XCB_SUPPORT           | Linux         | `ON`    | Build the loader with the XCB entry points enabled. Without this, the XCB headers should not be needed, but the extension `VK_KHR_xcb_surface` won't be available.                |
+| BUILD_WSI_XLIB_SUPPORT          | Linux         | `ON`    | Build the loader with the Xlib entry points enabled. Without this, the X11 headers should not be needed, but the extension `VK_KHR_xlib_surface` won't be available.              |
+| BUILD_WSI_WAYLAND_SUPPORT       | Linux         | `ON`    | Build the loader with the Wayland entry points enabled. Without this, the Wayland headers should not be needed, but the extension `VK_KHR_wayland_surface` won't be available.    |
+| BUILD_WSI_DIRECTFB_SUPPORT      | Linux         | `OFF`   | Build the loader with the DirectFB entry points enabled. Without this, the DirectFB headers should not be needed, but the extension `VK_EXT_directfb_surface` won't be available. |
+| BUILD_WSI_SCREEN_QNX_SUPPORT    | QNX           | `OFF`   | Build the loader with the QNX Screen entry points enabled. Without this the extension `VK_QNX_screen_surface` won't be available.                                                 |
+| ENABLE_WIN10_ONECORE            | Windows       | `OFF`   | Link the loader to the [OneCore](https://msdn.microsoft.com/en-us/library/windows/desktop/mt654039.aspx) umbrella library, instead of the standard Win32 ones.                    |
+| USE_GAS                         | Linux         | `ON`    | Controls whether to build assembly files with the GNU assembler, else fallback to C code.                                                                                         |
+| USE_MASM                        | Windows       | `ON`    | Controls whether to build assembly files with MS assembler, else fallback to C code                                                                                               |
+| BUILD_STATIC_LOADER             | macOS         | `OFF`   | This allows the loader to be built as a static library on macOS. Not tested, use at your own risk.                                                                                |
+| LOADER_ENABLE_ADDRESS_SANITIZER | Linux & macOS | `OFF`   | Enables Address Sanitizer in the loader and tests.                                                                                                                                |
+| LOADER_ENABLE_THREAD_SANITIZER  | Linux & macOS | `OFF`   | Enables Thread Sanitizer in the loader and tests.                                                                                                                                 |
+| LOADER_USE_UNSAFE_FILE_SEARCH   | All           | `OFF`   | Disables security policies that prevent unsecure locations from being used when running with elevated permissions.                                                                |
+| LOADER_CODEGEN                  | All           | `OFF`   | Creates a helper CMake target to generate code.                                                                                                                                   |
 
 NOTE: `LOADER_USE_UNSAFE_FILE_SEARCH` should NOT be enabled except in very specific contexts (like isolated test environments)!
 
index b2533ea..61c4ee5 100644 (file)
@@ -887,6 +887,26 @@ discovery.
         that would normally be enabled on the system.
     </small></td>
   </tr>
+  <tr>
+    <td><small>
+        <i>VK_LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING</i>
+    </small></td>
+    <td><small>
+        If set to "1", causes the loader to not unload dynamic libraries during vkDestroyInstance.
+        This option allows leak sanitizers to have full stack traces.
+    </small></td>
+    <td><small>
+        This functionality is only available with Loaders built with version
+        1.3.259 of the Vulkan headers and later.<br/>
+    </small></td>
+    <td><small>
+        export<br/>
+        &nbsp;&nbsp;VK_LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING=1<br/>
+        <br/>
+        set<br/>
+        &nbsp;&nbsp;VK_LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING=1<br/><br/>
+    </small></td>
+  </tr>
 </table>
 
 <br/>
index e1b0d71..2d0ec20 100644 (file)
@@ -382,11 +382,6 @@ if (LOADER_USE_UNSAFE_FILE_SEARCH)
     target_compile_definitions(vulkan PRIVATE LOADER_USE_UNSAFE_FILE_SEARCH)
 endif()
 
-option(LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING "Causes the loader to not unload dynamic libraries.")
-if (LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING)
-    target_compile_definitions(vulkan PRIVATE LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING)
-endif()
-
 # common attributes of the vulkan library
 target_link_libraries(vulkan PRIVATE loader_specific_options)
 
index c4903f0..5ee3be2 100644 (file)
@@ -96,6 +96,10 @@ loader_platform_thread_mutex loader_global_instance_list_lock;
 // vkCreateInstance.
 struct loader_icd_tramp_list scanned_icds;
 
+// controls whether loader_platform_close_library() closes the libraries or not - controlled by an environment
+// variables - this is just the definition of the variable, usage is in vk_loader_platform.h
+bool loader_disable_dynamic_library_unloading;
+
 LOADER_PLATFORM_THREAD_ONCE_DECLARATION(once_init);
 
 // Creates loader_api_version struct that contains the major and minor fields, setting patch to 0
@@ -1895,10 +1899,15 @@ void loader_initialize(void) {
     loader_log(NULL, VULKAN_LOADER_INFO_BIT, 0, "[Vulkan Loader Git - Tag: " GIT_BRANCH_NAME ", Branch/Commit: " GIT_TAG_INFO "]");
 #endif
 
-#if defined(LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING)
-    loader_log(NULL, VULKAN_LOADER_WARN_BIT, 0, "Vulkan Loader: library unloading is disabled");
-#endif
-
+    char *loader_disable_dynamic_library_unloading_env_var = loader_getenv("VK_LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING", NULL);
+    if (loader_disable_dynamic_library_unloading_env_var &&
+        0 == strncmp(loader_disable_dynamic_library_unloading_env_var, "1", 2)) {
+        loader_disable_dynamic_library_unloading = true;
+        loader_log(NULL, VULKAN_LOADER_WARN_BIT, 0, "Vulkan Loader: library unloading is disabled");
+    } else {
+        loader_disable_dynamic_library_unloading = false;
+    }
+    loader_free_getenv(loader_disable_dynamic_library_unloading_env_var, NULL);
 #if defined(LOADER_USE_UNSAFE_FILE_SEARCH)
     loader_log(NULL, VULKAN_LOADER_WARN_BIT, 0, "Vulkan Loader: unsafe searching is enabled");
 #endif
index 1fbdf97..a2d0027 100644 (file)
@@ -214,6 +214,9 @@ typedef CONDITION_VARIABLE loader_platform_thread_cond;
 
 #endif
 
+// controls whether loader_platform_close_library() closes the libraries or not - controlled by an environment variables
+extern bool loader_disable_dynamic_library_unloading;
+
 // Returns true if the DIRECTORY_SYMBOL is contained within path
 static inline bool loader_platform_is_path(const char *path) { return strchr(path, DIRECTORY_SYMBOL) != NULL; }
 
@@ -363,12 +366,11 @@ static inline const char *loader_platform_open_library_error(const char *libPath
 #endif
 }
 static inline void loader_platform_close_library(loader_platform_dl_handle library) {
-#if defined(LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING)
-    (void)library;
-    return;
-#else
-    dlclose(library);
-#endif
+    if (!loader_disable_dynamic_library_unloading) {
+        dlclose(library);
+    } else {
+        (void)library;
+    }
 }
 static inline void *loader_platform_get_proc_address(loader_platform_dl_handle library, const char *name) {
     assert(library);
@@ -519,12 +521,11 @@ static inline const char *loader_platform_open_library_error(const char *libPath
     return errorMsg;
 }
 static inline void loader_platform_close_library(loader_platform_dl_handle library) {
-#if defined(LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING)
-    (void)library;
-    return;
-#else
-    FreeLibrary(library);
-#endif
+    if (!loader_disable_dynamic_library_unloading) {
+        FreeLibrary(library);
+    } else {
+        (void)library;
+    }
 }
 static inline void *loader_platform_get_proc_address(loader_platform_dl_handle library, const char *name) {
     assert(library);