vsk created this revision. vsk added a reviewer: jingham. Herald added a subscriber: emaste. vsk requested review of this revision. Herald added a project: LLDB.
In general, it seems like the debugger should allow programs to load & run with libraries as far as possible, instead of defaulting to being super-picky about unavailable symbols. This is critical on macOS/Darwin, as libswiftCore.dylib may 1) export a version symbol using @available markup and then 2) expect that other exported APIs are only dynamically used once the version symbol is checked. We can't open a version of the library built with a bleeding-edge SDK on an older OS without RTLD_LAXY (or pervasive/expensive @available markup added to dyld APIs). See: https://lists.llvm.org/pipermail/lldb-dev/2021-March/016796.html Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D98879 Files: lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp Index: lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp =================================================================== --- lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -573,6 +573,21 @@ std::unique_ptr<UtilityFunction> PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx, Status &error) { + // Use lazy binding so as to not make dlopen()'s success conditional on + // forcing every symbol in the library. This is critical on macOS/Darwin, as + // a library may 1) export a version symbol using @available markup and then + // 2) expect that other exported APIs are only dynamically used once the + // version symbol is checked. (Previously, LLDB used RTLD_NOW=2, which made + // it impossible to load such libraries (e.g. libswiftCore.dylib)). + // + // In general, the debugger should allow programs to load & run with + // libraries as far as they can, instead of defaulting to being super-picky + // about unavailable symbols. + // + // The value "1" appears to imply lazy binding (RTLD_LAZY) on both Darwin + // and other POSIX OSes. +#define DLOPEN_OPTIONS "1" + // Remember to prepend this with the prefix from // GetLibdlFunctionDeclarations. The returned values are all in // __lldb_dlopen_result for consistency. The wrapper returns a void * but @@ -595,7 +610,7 @@ { // This is the case where the name is the full path: if (!path_strings) { - result_ptr->image_ptr = dlopen(name, 2); + result_ptr->image_ptr = dlopen(name, )" DLOPEN_OPTIONS R"(); if (result_ptr->image_ptr) result_ptr->error_str = nullptr; return nullptr; @@ -609,7 +624,7 @@ buffer[path_len] = '/'; char *target_ptr = buffer+path_len+1; memcpy((void *) target_ptr, (void *) name, name_len + 1); - result_ptr->image_ptr = dlopen(buffer, 2); + result_ptr->image_ptr = dlopen(buffer, )" DLOPEN_OPTIONS R"(); if (result_ptr->image_ptr) { result_ptr->error_str = nullptr; break; @@ -620,6 +635,7 @@ return nullptr; } )"; +#undef DLOPEN_OPTIONS static const char *dlopen_wrapper_name = "__lldb_dlopen_wrapper"; Process *process = exe_ctx.GetProcessSP().get();
Index: lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp =================================================================== --- lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -573,6 +573,21 @@ std::unique_ptr<UtilityFunction> PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx, Status &error) { + // Use lazy binding so as to not make dlopen()'s success conditional on + // forcing every symbol in the library. This is critical on macOS/Darwin, as + // a library may 1) export a version symbol using @available markup and then + // 2) expect that other exported APIs are only dynamically used once the + // version symbol is checked. (Previously, LLDB used RTLD_NOW=2, which made + // it impossible to load such libraries (e.g. libswiftCore.dylib)). + // + // In general, the debugger should allow programs to load & run with + // libraries as far as they can, instead of defaulting to being super-picky + // about unavailable symbols. + // + // The value "1" appears to imply lazy binding (RTLD_LAZY) on both Darwin + // and other POSIX OSes. +#define DLOPEN_OPTIONS "1" + // Remember to prepend this with the prefix from // GetLibdlFunctionDeclarations. The returned values are all in // __lldb_dlopen_result for consistency. The wrapper returns a void * but @@ -595,7 +610,7 @@ { // This is the case where the name is the full path: if (!path_strings) { - result_ptr->image_ptr = dlopen(name, 2); + result_ptr->image_ptr = dlopen(name, )" DLOPEN_OPTIONS R"(); if (result_ptr->image_ptr) result_ptr->error_str = nullptr; return nullptr; @@ -609,7 +624,7 @@ buffer[path_len] = '/'; char *target_ptr = buffer+path_len+1; memcpy((void *) target_ptr, (void *) name, name_len + 1); - result_ptr->image_ptr = dlopen(buffer, 2); + result_ptr->image_ptr = dlopen(buffer, )" DLOPEN_OPTIONS R"(); if (result_ptr->image_ptr) { result_ptr->error_str = nullptr; break; @@ -620,6 +635,7 @@ return nullptr; } )"; +#undef DLOPEN_OPTIONS static const char *dlopen_wrapper_name = "__lldb_dlopen_wrapper"; Process *process = exe_ctx.GetProcessSP().get();
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits