[Lldb-commits] [lldb] cb8c1ee - [lldb/PlatformPOSIX] Change LoadImage default to RTLD_LAZY
Vedant Kumar via lldb-commits
lldb-commits at lists.llvm.org
Fri Mar 19 15:13:53 PDT 2021
Author: Vedant Kumar
Date: 2021-03-19T15:13:43-07:00
New Revision: cb8c1ee269da72eb6e2c18800cd8ab0a74050785
URL: https://github.com/llvm/llvm-project/commit/cb8c1ee269da72eb6e2c18800cd8ab0a74050785
DIFF: https://github.com/llvm/llvm-project/commit/cb8c1ee269da72eb6e2c18800cd8ab0a74050785.diff
LOG: [lldb/PlatformPOSIX] Change LoadImage default to RTLD_LAZY
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
Differential Revision: https://reviews.llvm.org/D98879
Added:
lldb/test/API/functionalities/load_lazy/Makefile
lldb/test/API/functionalities/load_lazy/TestLoadUsingLazyBind.py
lldb/test/API/functionalities/load_lazy/categories
lldb/test/API/functionalities/load_lazy/main.cpp
lldb/test/API/functionalities/load_lazy/t1.c
lldb/test/API/functionalities/load_lazy/t2_0.c
lldb/test/API/functionalities/load_lazy/t2_1.c
Modified:
lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index c8a006001fcb..3e5f1451ef5f 100644
--- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -578,7 +578,19 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
// __lldb_dlopen_result for consistency. The wrapper returns a void * but
// doesn't use it because UtilityFunctions don't work with void returns at
// present.
+ //
+ // Use lazy binding so as to not make dlopen()'s success conditional on
+ // forcing every symbol in the library.
+ //
+ // 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.
static const char *dlopen_wrapper_code = R"(
+ const int RTLD_LAZY = 1;
+
struct __lldb_dlopen_result {
void *image_ptr;
const char *error_str;
@@ -595,7 +607,7 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
{
// 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, RTLD_LAZY);
if (result_ptr->image_ptr)
result_ptr->error_str = nullptr;
return nullptr;
@@ -609,7 +621,7 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
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, RTLD_LAZY);
if (result_ptr->image_ptr) {
result_ptr->error_str = nullptr;
break;
diff --git a/lldb/test/API/functionalities/load_lazy/Makefile b/lldb/test/API/functionalities/load_lazy/Makefile
new file mode 100644
index 000000000000..14eff232bb6d
--- /dev/null
+++ b/lldb/test/API/functionalities/load_lazy/Makefile
@@ -0,0 +1,17 @@
+CXX_SOURCES := main.cpp
+
+all: t2_0 t2_1 t1 a.out
+
+include Makefile.rules
+
+t1: t2_0
+ $(MAKE) VPATH=$(SRCDIR) -f $(MAKEFILE_RULES) \
+ DYLIB_ONLY=YES DYLIB_C_SOURCES=t1.c DYLIB_NAME=t1 LD_EXTRAS="-L. -lt2_0"
+
+t2_0:
+ $(MAKE) VPATH=$(SRCDIR) -f $(MAKEFILE_RULES) \
+ DYLIB_ONLY=YES DYLIB_C_SOURCES=t2_0.c DYLIB_NAME=t2_0
+
+t2_1:
+ $(MAKE) VPATH=$(SRCDIR) -f $(MAKEFILE_RULES) \
+ DYLIB_ONLY=YES DYLIB_C_SOURCES=t2_1.c DYLIB_NAME=t2_1
diff --git a/lldb/test/API/functionalities/load_lazy/TestLoadUsingLazyBind.py b/lldb/test/API/functionalities/load_lazy/TestLoadUsingLazyBind.py
new file mode 100644
index 000000000000..18135a18bdaf
--- /dev/null
+++ b/lldb/test/API/functionalities/load_lazy/TestLoadUsingLazyBind.py
@@ -0,0 +1,54 @@
+"""
+Test that SBProcess.LoadImageUsingPaths uses RTLD_LAZY
+"""
+
+
+
+import os
+import shutil
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+ at skipIfRemote
+ at skipIfWindows # The Windows platform doesn't implement DoLoadImage.
+class LoadUsingLazyBind(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ # Invoke the default build rule.
+ self.build()
+
+ self.wd = os.path.realpath(self.getBuildDir())
+
+ self.ext = 'so'
+ if self.platformIsDarwin():
+ self.ext = 'dylib'
+
+ # Overwrite t2_0 with t2_1 to delete the definition of `use`.
+ shutil.copy(os.path.join(self.wd, 'libt2_1.{}'.format(self.ext)),
+ os.path.join(self.wd, 'libt2_0.{}'.format(self.ext)))
+
+ @skipIfRemote
+ @skipIfWindows # The Windows platform doesn't implement DoLoadImage.
+ def test_load_using_lazy_bind(self):
+ """Test that we load using RTLD_LAZY"""
+
+ (target, process, thread, _) = lldbutil.run_to_source_breakpoint(self,
+ "break here",
+ lldb.SBFileSpec("main.cpp"))
+ error = lldb.SBError()
+ lib_spec = lldb.SBFileSpec("libt1.{}".format(self.ext))
+ paths = lldb.SBStringList()
+ paths.AppendString(self.wd)
+ out_spec = lldb.SBFileSpec()
+ token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error)
+ self.assertNotEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token")
diff --git a/lldb/test/API/functionalities/load_lazy/categories b/lldb/test/API/functionalities/load_lazy/categories
new file mode 100644
index 000000000000..c00c25822e4c
--- /dev/null
+++ b/lldb/test/API/functionalities/load_lazy/categories
@@ -0,0 +1 @@
+basic_process
diff --git a/lldb/test/API/functionalities/load_lazy/main.cpp b/lldb/test/API/functionalities/load_lazy/main.cpp
new file mode 100644
index 000000000000..ba45ee316cd4
--- /dev/null
+++ b/lldb/test/API/functionalities/load_lazy/main.cpp
@@ -0,0 +1,3 @@
+int main() {
+ return 0; // break here
+}
diff --git a/lldb/test/API/functionalities/load_lazy/t1.c b/lldb/test/API/functionalities/load_lazy/t1.c
new file mode 100644
index 000000000000..08eae300490f
--- /dev/null
+++ b/lldb/test/API/functionalities/load_lazy/t1.c
@@ -0,0 +1,3 @@
+extern void use();
+void f1() {}
+void f2() { use(); }
diff --git a/lldb/test/API/functionalities/load_lazy/t2_0.c b/lldb/test/API/functionalities/load_lazy/t2_0.c
new file mode 100644
index 000000000000..9fc1edfbf460
--- /dev/null
+++ b/lldb/test/API/functionalities/load_lazy/t2_0.c
@@ -0,0 +1 @@
+void use() {}
diff --git a/lldb/test/API/functionalities/load_lazy/t2_1.c b/lldb/test/API/functionalities/load_lazy/t2_1.c
new file mode 100644
index 000000000000..e69de29bb2d1
More information about the lldb-commits
mailing list