diff --git a/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py b/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py --- a/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py +++ b/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py @@ -178,7 +178,7 @@ elif getPlatform() in ("freebsd", "linux", "netbsd"): return _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so') else: - return None + return _PlatformContext('PATH', '', 'dll') def hasChattyStderr(test_case): diff --git a/lldb/packages/Python/lldbsuite/test/make/Makefile.rules b/lldb/packages/Python/lldbsuite/test/make/Makefile.rules --- a/lldb/packages/Python/lldbsuite/test/make/Makefile.rules +++ b/lldb/packages/Python/lldbsuite/test/make/Makefile.rules @@ -474,7 +474,7 @@ # Additional system libraries #---------------------------------------------------------------------- ifeq (1,$(USE_LIBDL)) - ifneq ($(OS),NetBSD) + ifeq (,$(filter $(OS), NetBSD Windows_NT)) LDFLAGS += -ldl endif endif diff --git a/lldb/packages/Python/lldbsuite/test/make/dylib.h b/lldb/packages/Python/lldbsuite/test/make/dylib.h new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/make/dylib.h @@ -0,0 +1,55 @@ +#ifndef LLDB_TEST_DYLIB_H +#define LLDB_TEST_DYLIB_H + +#include + +#ifdef _WIN32 +#include + +#define dylib_get_symbol(handle, name) GetProcAddress((HMODULE)handle, name) +#define dylib_close(handle) (!FreeLibrary((HMODULE)handle)) +#else +#include + +#define dylib_get_symbol(handle, name) dlsym(handle, name) +#define dylib_close(handle) dlclose(handle) +#endif + + +inline void *dylib_open(const char *name) { + char dylib_prefix[] = +#ifdef _WIN32 + ""; +#else + "lib"; +#endif + char dylib_suffix[] = +#ifdef _WIN32 + ".dll"; +#elif defined(__APPLE__) + ".dylib"; +#else + ".so"; +#endif + char fullname[1024]; + strcat(strcat(strcpy(fullname, dylib_prefix), name), dylib_suffix); +#ifdef _WIN32 + return LoadLibraryA(fullname); +#else + return dlopen(fullname, RTLD_NOW); +#endif +} + +inline const char *dylib_last_error() { +#ifndef _WIN32 + return dlerror(); +#else + DWORD err = GetLastError(); + char *msg; + FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *)&msg, 0, NULL); + return msg; +#endif +} + +#endif diff --git a/lldb/packages/Python/lldbsuite/test/make/test_common.h b/lldb/packages/Python/lldbsuite/test/make/test_common.h --- a/lldb/packages/Python/lldbsuite/test/make/test_common.h +++ b/lldb/packages/Python/lldbsuite/test/make/test_common.h @@ -1,13 +1,18 @@ // This header is included in all the test programs (C and C++) and provides a // hook for dealing with platform-specifics. + #if defined(_WIN32) || defined(_WIN64) -#ifdef COMPILING_LLDB_TEST_DLL -#define LLDB_TEST_API __declspec(dllexport) +#define LLDB_DYLIB_EXPORT __declspec(dllexport) +#define LLDB_DYLIB_IMPORT __declspec(dllimport) #else -#define LLDB_TEST_API __declspec(dllimport) +#define LLDB_DYLIB_EXPORT +#define LLDB_DYLIB_IMPORT #endif + +#ifdef COMPILING_LLDB_TEST_DLL +#define LLDB_TEST_API LLDB_DYLIB_EXPORT #else -#define LLDB_TEST_API +#define LLDB_TEST_API LLDB_DYLIB_IMPORT #endif #if defined(_WIN32) diff --git a/lldb/test/API/functionalities/load_unload/Makefile b/lldb/test/API/functionalities/load_unload/Makefile --- a/lldb/test/API/functionalities/load_unload/Makefile +++ b/lldb/test/API/functionalities/load_unload/Makefile @@ -26,7 +26,9 @@ install_name_tool -id @executable_path/libloadunload_d.dylib libloadunload_d.dylib endif -hidden_lib_d: - mkdir -p hidden +hidden: + mkdir hidden + +hidden_lib_d: hidden $(MAKE) VPATH=$(SRCDIR)/hidden -C hidden -f $(MAKEFILE_RULES) \ DYLIB_ONLY=YES DYLIB_CXX_SOURCES=d.cpp DYLIB_NAME=loadunload_d diff --git a/lldb/test/API/functionalities/load_unload/TestLoadUnload.py b/lldb/test/API/functionalities/load_unload/TestLoadUnload.py --- a/lldb/test/API/functionalities/load_unload/TestLoadUnload.py +++ b/lldb/test/API/functionalities/load_unload/TestLoadUnload.py @@ -13,7 +13,6 @@ from lldbsuite.test import lldbutil -@skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently class LoadUnloadTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) @@ -206,6 +205,9 @@ substrs=[os.path.basename(old_dylib)], matching=True) + env_cmd_string = "settings set target.env-vars " + self.dylibPath + "=" + self.getBuildArtifact(".") + self.runCmd(env_cmd_string) + lldbutil.run_break_set_by_file_and_line( self, "d.cpp", self.line_d_function, num_expected_locations=1) # After run, make sure the non-hidden library is picked up. @@ -216,8 +218,7 @@ # Add the hidden directory first in the search path. env_cmd_string = ("settings set target.env-vars %s=%s" % (self.dylibPath, new_dir)) - if not self.platformIsDarwin(): - env_cmd_string += ":" + wd + env_cmd_string += ":" + wd self.runCmd(env_cmd_string) # This time, the hidden library should be picked up. @@ -228,7 +229,7 @@ hostoslist=["windows"], triple='.*-android') @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support - @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently + @expectedFailureAll(oslist=["windows"]) # process load not implemented def test_lldb_process_load_and_unload_commands(self): self.setSvr4Support(False) self.run_lldb_process_load_and_unload_commands() @@ -238,7 +239,7 @@ hostoslist=["windows"], triple='.*-android') @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support - @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently + @expectedFailureAll(oslist=["windows"]) # process load not implemented def test_lldb_process_load_and_unload_commands_with_svr4(self): self.setSvr4Support(True) self.run_lldb_process_load_and_unload_commands() @@ -314,11 +315,13 @@ self.runCmd("process continue") @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support + @expectedFailureAll(oslist=["windows"]) # breakpoint not hit def test_load_unload(self): self.setSvr4Support(False) self.run_load_unload() @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support + @expectedFailureAll(oslist=["windows"]) # breakpoint not hit def test_load_unload_with_svr4(self): self.setSvr4Support(True) self.run_load_unload() @@ -327,6 +330,9 @@ """Test breakpoint by name works correctly with dlopen'ing.""" self.copy_shlibs_to_remote() + env_cmd_string = "settings set target.env-vars " + self.dylibPath + "=" + self.getBuildArtifact(".") + self.runCmd(env_cmd_string) + exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) @@ -362,7 +368,6 @@ substrs=[' resolved, hit count = 2']) @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support - @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently @expectedFailureAll(archs="aarch64", oslist="linux", bugnumber="https://bugs.llvm.org/show_bug.cgi?id=27806") def test_step_over_load(self): @@ -370,7 +375,6 @@ self.run_step_over_load() @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support - @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently @expectedFailureAll(archs="aarch64", oslist="linux", bugnumber="https://bugs.llvm.org/show_bug.cgi?id=27806") def test_step_over_load_with_svr4(self): @@ -408,11 +412,12 @@ # executable dependencies are resolved relative to the debuggers PWD. Bug? @expectedFailureAll(oslist=["linux"], triple=no_match('aarch64-.*-android')) @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support - @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently @expectedFailureNetBSD def test_static_init_during_load(self): """Test that we can set breakpoints correctly in static initializers""" self.copy_shlibs_to_remote() + env_cmd_string = "settings set target.env-vars " + self.dylibPath + "=" + self.getBuildArtifact(".") + self.runCmd(env_cmd_string) exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) @@ -438,7 +443,7 @@ 'stop reason = breakpoint %d' % b_init_bp_num]) self.expect("thread backtrace", substrs=['b_init', - 'dlopen', + 'dylib_open', 'main']) self.runCmd("continue") @@ -448,5 +453,5 @@ 'stop reason = breakpoint %d' % a_init_bp_num]) self.expect("thread backtrace", substrs=['a_init', - 'dlopen', + 'dylib_open', 'main']) diff --git a/lldb/test/API/functionalities/load_unload/a.cpp b/lldb/test/API/functionalities/load_unload/a.cpp --- a/lldb/test/API/functionalities/load_unload/a.cpp +++ b/lldb/test/API/functionalities/load_unload/a.cpp @@ -1,4 +1,4 @@ -extern int b_function (); +extern LLDB_DYLIB_IMPORT int b_function(); int a_init() { diff --git a/lldb/test/API/functionalities/load_unload/b.cpp b/lldb/test/API/functionalities/load_unload/b.cpp --- a/lldb/test/API/functionalities/load_unload/b.cpp +++ b/lldb/test/API/functionalities/load_unload/b.cpp @@ -5,8 +5,4 @@ int b_global = b_init(); -int -b_function () -{ - return 500; -} +int LLDB_DYLIB_EXPORT b_function() { return 500; } diff --git a/lldb/test/API/functionalities/load_unload/d.cpp b/lldb/test/API/functionalities/load_unload/d.cpp --- a/lldb/test/API/functionalities/load_unload/d.cpp +++ b/lldb/test/API/functionalities/load_unload/d.cpp @@ -5,8 +5,6 @@ int d_global = d_init(); -int -d_function () -{ // Find this line number within d_dunction(). - return 700; +int LLDB_DYLIB_EXPORT d_function() { + return 700; // Find this line number within d_dunction(). } diff --git a/lldb/test/API/functionalities/load_unload/main.cpp b/lldb/test/API/functionalities/load_unload/main.cpp --- a/lldb/test/API/functionalities/load_unload/main.cpp +++ b/lldb/test/API/functionalities/load_unload/main.cpp @@ -1,71 +1,62 @@ -#include -#include +#include "dylib.h" #include -#include -#include -#include +#include #include +#include int main (int argc, char const *argv[]) { -#if defined (__APPLE__) - const char *a_name = "@executable_path/libloadunload_a.dylib"; - const char *c_name = "@executable_path/libloadunload_c.dylib"; -#else - const char *a_name = "libloadunload_a.so"; - const char *c_name = "libloadunload_c.so"; -#endif - void *a_dylib_handle = NULL; - void *c_dylib_handle = NULL; - int (*a_function) (void); - - a_dylib_handle = dlopen (a_name, RTLD_NOW); // Set break point at this line for test_lldb_process_load_and_unload_commands(). - if (a_dylib_handle == NULL) - { - fprintf (stderr, "%s\n", dlerror()); - exit (1); - } - - a_function = (int (*) ()) dlsym (a_dylib_handle, "a_function"); - if (a_function == NULL) - { - fprintf (stderr, "%s\n", dlerror()); - exit (2); - } + const char *a_name = "loadunload_a"; + const char *c_name = "loadunload_c"; + void *a_dylib_handle = NULL; + void *c_dylib_handle = NULL; // Set break point at this line for test_lldb_process_load_and_unload_commands(). + int (*a_function)(void); + + a_dylib_handle = dylib_open(a_name); + if (a_dylib_handle == NULL) { + fprintf(stderr, "%s\n", dylib_last_error()); + exit(1); + } + + a_function = (int (*)())dylib_get_symbol(a_dylib_handle, "a_function"); + if (a_function == NULL) { + fprintf(stderr, "%s\n", dylib_last_error()); + exit(2); + } printf ("First time around, got: %d\n", a_function ()); - dlclose (a_dylib_handle); + dylib_close(a_dylib_handle); - c_dylib_handle = dlopen (c_name, RTLD_NOW); + c_dylib_handle = dylib_open(c_name); if (c_dylib_handle == NULL) { - fprintf (stderr, "%s\n", dlerror()); - exit (3); + fprintf(stderr, "%s\n", dylib_last_error()); + exit(3); } - a_function = (int (*) ()) dlsym (c_dylib_handle, "c_function"); + a_function = (int (*)())dylib_get_symbol(c_dylib_handle, "c_function"); if (a_function == NULL) { - fprintf (stderr, "%s\n", dlerror()); - exit (4); + fprintf(stderr, "%s\n", dylib_last_error()); + exit(4); } - a_dylib_handle = dlopen (a_name, RTLD_NOW); + a_dylib_handle = dylib_open(a_name); if (a_dylib_handle == NULL) { - fprintf (stderr, "%s\n", dlerror()); - exit (5); + fprintf(stderr, "%s\n", dylib_last_error()); + exit(5); } - a_function = (int (*) ()) dlsym (a_dylib_handle, "a_function"); + a_function = (int (*)())dylib_get_symbol(a_dylib_handle, "a_function"); if (a_function == NULL) { - fprintf (stderr, "%s\n", dlerror()); - exit (6); + fprintf(stderr, "%s\n", dylib_last_error()); + exit(6); } printf ("Second time around, got: %d\n", a_function ()); - dlclose (a_dylib_handle); + dylib_close(a_dylib_handle); - int d_function(void); + int LLDB_DYLIB_IMPORT d_function(void); printf ("d_function returns: %d\n", d_function()); return 0;