diff --git a/renderdoc/os/posix/linux/linux_hook.cpp b/renderdoc/os/posix/linux/linux_hook.cpp index 9555d0b97..9a090efe3 100644 --- a/renderdoc/os/posix/linux/linux_hook.cpp +++ b/renderdoc/os/posix/linux/linux_hook.cpp @@ -45,6 +45,8 @@ void plthook_lib(void *handle); typedef void *(*DLOPENPROC)(const char *, int); DLOPENPROC realdlopen = NULL; +static volatile int32_t tlsbusyflag = 0; + __attribute__((visibility("default"))) void *dlopen(const char *filename, int flag) { if(!realdlopen) @@ -59,7 +61,10 @@ __attribute__((visibility("default"))) void *dlopen(const char *filename, int fl return ret; } + // don't do any hook processing inside here even if we call dlopen again + Atomic::Inc32(&tlsbusyflag); void *ret = realdlopen(filename, flag); + Atomic::Dec32(&tlsbusyflag); if(filename && ret) { @@ -85,6 +90,10 @@ void plthook_lib(void *handle) static void CheckLoadedLibraries() { + // don't process anything if the busy flag was set, otherwise set it ourselves + if(Atomic::CmpExch32(&tlsbusyflag, 0, 1) != 0) + return; + // iterate over the libraries and see which ones are already loaded, process function hooks for // them and call callbacks. for(auto it = libraryHooks.begin(); it != libraryHooks.end(); ++it) @@ -110,6 +119,9 @@ static void CheckLoadedLibraries() cb(handle); } } + + // decrement the flag counter + Atomic::Dec32(&tlsbusyflag); } void *intercept_dlopen(const char *filename, int flag, void *ret)