alvinhochun created this revision. alvinhochun added reviewers: labath, mstorsjo, clayborg, jingham. Herald added a project: All. alvinhochun requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
LLDB preloads some dependent modules when creating the target. On Windows, when the target is run and the dependent DLLs are actually loaded by the process, `ProcessWindows::OnLoadDll` calls `DynamicLoaderWindowsDYLD::OnLoadModule` which in turn calls `Target::GetOrCreateModule` to try to load the DLL module. However, it did not properly handle the case of getting an already-preloaded module, and as a result any dependent DLLs preloaded by LLDB will end up being duplicated in the target module list and causing some commands to return repeated results (e.g. `target modules lookup`). This issue does not seem to affect Linux, because the codepath it uses, which goes through `DynamicLoader::FindModuleViaTarget`, has an additional check to find existing modules before calling `Target::GetOrCreateModule`. This patch adds an early return to `Target::GetOrCreateModule` for when it finds a pre-existing module already in the target module list to fix the issue for Windows. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D134581 Files: lldb/source/Target/Target.cpp lldb/test/Shell/Target/Inputs/main.c lldb/test/Shell/Target/Inputs/shlib.c lldb/test/Shell/Target/dependent-modules-nodupe-windows.test Index: lldb/test/Shell/Target/dependent-modules-nodupe-windows.test =================================================================== --- /dev/null +++ lldb/test/Shell/Target/dependent-modules-nodupe-windows.test @@ -0,0 +1,20 @@ +# REQUIRES: system-windows + +# Checks that dependent modules preloaded by LLDB are not duplicated when the +# process actually loads the DLL. + +# RUN: %clang_host -g0 -O0 -shared %S/Inputs/shlib.c -o %t.shlib.dll +# RUN: %clang_host -g0 -O0 %S/Inputs/main.c %t.shlib.dll -o %t.main.exe +# RUN: %lldb -b -o "#before" -o "target modules list" -o "b main" -o run \ +# RUN: -o "#after" -o "target modules list" %t.main.exe | FileCheck %s + +# CHECK-LABEL: #before +# CHECK-NEXT: target modules list +# CHECK-NEXT: .main.exe +# CHECK-NEXT: .shlib.dll + +# CHECK-LABEL: #after +# CHECK-NEXT: target modules list +# CHECK-NEXT: .main.exe +# CHECK-NEXT: .shlib.dll +# CHECK-NOT: .shlib.dll Index: lldb/test/Shell/Target/Inputs/shlib.c =================================================================== --- /dev/null +++ lldb/test/Shell/Target/Inputs/shlib.c @@ -0,0 +1 @@ +__declspec(dllexport) void exportFunc(void) {} Index: lldb/test/Shell/Target/Inputs/main.c =================================================================== --- /dev/null +++ lldb/test/Shell/Target/Inputs/main.c @@ -0,0 +1,2 @@ +__declspec(dllimport) void exportFunc(void); +int main() { exportFunc(); } Index: lldb/source/Target/Target.cpp =================================================================== --- lldb/source/Target/Target.cpp +++ lldb/source/Target/Target.cpp @@ -2134,6 +2134,13 @@ } } + // If we found a pre-existing module, just return it. + if (module_sp && !did_create_module) { + if (error_ptr) + *error_ptr = error; + return module_sp; + } + // We found a module that wasn't in our target list. Let's make sure that // there wasn't an equivalent module in the list already, and if there was, // let's remove it.
Index: lldb/test/Shell/Target/dependent-modules-nodupe-windows.test =================================================================== --- /dev/null +++ lldb/test/Shell/Target/dependent-modules-nodupe-windows.test @@ -0,0 +1,20 @@ +# REQUIRES: system-windows + +# Checks that dependent modules preloaded by LLDB are not duplicated when the +# process actually loads the DLL. + +# RUN: %clang_host -g0 -O0 -shared %S/Inputs/shlib.c -o %t.shlib.dll +# RUN: %clang_host -g0 -O0 %S/Inputs/main.c %t.shlib.dll -o %t.main.exe +# RUN: %lldb -b -o "#before" -o "target modules list" -o "b main" -o run \ +# RUN: -o "#after" -o "target modules list" %t.main.exe | FileCheck %s + +# CHECK-LABEL: #before +# CHECK-NEXT: target modules list +# CHECK-NEXT: .main.exe +# CHECK-NEXT: .shlib.dll + +# CHECK-LABEL: #after +# CHECK-NEXT: target modules list +# CHECK-NEXT: .main.exe +# CHECK-NEXT: .shlib.dll +# CHECK-NOT: .shlib.dll Index: lldb/test/Shell/Target/Inputs/shlib.c =================================================================== --- /dev/null +++ lldb/test/Shell/Target/Inputs/shlib.c @@ -0,0 +1 @@ +__declspec(dllexport) void exportFunc(void) {} Index: lldb/test/Shell/Target/Inputs/main.c =================================================================== --- /dev/null +++ lldb/test/Shell/Target/Inputs/main.c @@ -0,0 +1,2 @@ +__declspec(dllimport) void exportFunc(void); +int main() { exportFunc(); } Index: lldb/source/Target/Target.cpp =================================================================== --- lldb/source/Target/Target.cpp +++ lldb/source/Target/Target.cpp @@ -2134,6 +2134,13 @@ } } + // If we found a pre-existing module, just return it. + if (module_sp && !did_create_module) { + if (error_ptr) + *error_ptr = error; + return module_sp; + } + // We found a module that wasn't in our target list. Let's make sure that // there wasn't an equivalent module in the list already, and if there was, // let's remove it.
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits