Index: lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp =================================================================== --- lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -556,7 +556,8 @@ } } - if (exe_idx != UINT32_MAX) { + // Set the target executable if we haven't found one so far. + if (exe_idx != UINT32_MAX && !target.GetExecutableModule()) { const bool can_create = true; ModuleSP exe_module_sp(FindTargetModuleForImageInfo(image_infos[exe_idx], can_create, nullptr)); Index: lldb/test/API/functionalities/dlopen_other_executable/Makefile =================================================================== --- /dev/null +++ lldb/test/API/functionalities/dlopen_other_executable/Makefile @@ -0,0 +1,8 @@ +C_SOURCES := main.c +USE_LIBDL := 1 + +other: + $(MAKE) -f $(MAKEFILE_RULES) C_SOURCES=other.c EXE=other +all: other + +include Makefile.rules Index: lldb/test/API/functionalities/dlopen_other_executable/TestDlopenOtherExecutable.py =================================================================== --- /dev/null +++ lldb/test/API/functionalities/dlopen_other_executable/TestDlopenOtherExecutable.py @@ -0,0 +1,26 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfRemote + @skipIfWindows + @no_debug_info_test + def test(self): + self.build() + # Launch and stop before the dlopen call. + lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.c")) + # Check that the executable is the test binary. + self.assertEqual(self.target().GetExecutable().GetFilename(), "a.out") + # Continue so that dlopen is called. + breakpoint = self.target().BreakpointCreateBySourceRegex( + "// break after dlopen", lldb.SBFileSpec("main.c")) + self.assertTrue(breakpoint.IsValid()) + stopped_threads = lldbutil.continue_to_breakpoint(self.process(), breakpoint) + self.assertEqual(len(stopped_threads), 1) + # Check that the executable is still the test binary and not "other". + self.assertEqual(self.target().GetExecutable().GetFilename(), "a.out") Index: lldb/test/API/functionalities/dlopen_other_executable/main.c =================================================================== --- /dev/null +++ lldb/test/API/functionalities/dlopen_other_executable/main.c @@ -0,0 +1,8 @@ +#include + +int main() { + int i = 0; // break here + // dlopen the 'other' test executable. + dlopen("other", RTLD_LAZY); + return i; // break after dlopen +} Index: lldb/test/API/functionalities/dlopen_other_executable/other.c =================================================================== --- /dev/null +++ lldb/test/API/functionalities/dlopen_other_executable/other.c @@ -0,0 +1 @@ +int main() {}