Skip to content

Commit

Permalink
[windows] Fix self-path lookup on Windows (#103)
Browse files Browse the repository at this point in the history
Store handle to self in `DllMain` so that we don't try to figure out a
handle to ourselves (incorrectly) anymore on Windows.

Add test for LBT path printing when `LBT_VERBOSE=1`
  • Loading branch information
staticfloat authored Feb 7, 2023
1 parent 8b8c2e3 commit 165da4c
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 5 deletions.
5 changes: 3 additions & 2 deletions src/dl_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,11 @@ void * lookup_symbol(const void * handle, const char * symbol_name) {
* Work around protected symbol visibility and GCC/ld.bfd bug:
* https://sourceware.org/bugzilla/show_bug.cgi?id=26815
*/
extern void * _win32_self_handle;
void * lookup_self_symbol(const char * symbol_name) {
void * self_handle = NULL;
#if defined(_OS_WINDOWS_)
self_handle = GetModuleHandle(NULL);
self_handle = _win32_self_handle;
#elif defined(_OS_DARWIN_)
self_handle = RTLD_SELF;
#elif defined(RTLD_DEFAULT)
Expand All @@ -104,7 +105,7 @@ const char * lookup_self_path()
return self_path;
}
#if defined(_OS_WINDOWS_)
if (!GetModuleFileNameA(GetModuleHandle(NULL), self_path, PATH_MAX)) {
if (!GetModuleFileNameA(_win32_self_handle, self_path, PATH_MAX)) {
fprintf(stderr, "ERROR: GetModuleFileName() failed\n");
strcpy(self_path, "<unknown>");
return self_path;
Expand Down
17 changes: 16 additions & 1 deletion src/libblastrampoline.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,19 @@ LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t v
return nforwards;
}


/*
* On windows it's surprisingly difficult to get a handle to ourselves,
* and that's because they give it to you in `DllMain()`. ;)
*/
#ifdef _OS_WINDOWS_
void * _win32_self_handle;
BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD code, void *) {
if (code == DLL_PROCESS_ATTACH) {
_win32_self_handle = (void *)hModule;
}
#else
__attribute__((constructor)) void init(void) {
#endif
// Initialize config structures
init_config();

Expand Down Expand Up @@ -457,4 +468,8 @@ __attribute__((constructor)) void init(void) {
clear = 0;
}
}

#ifdef _OS_WINDOWS_
return TRUE;
#endif
}
2 changes: 1 addition & 1 deletion src/win_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ int utf8_to_wchar(const char * str, wchar_t * wstr, size_t maxlen) {
if (!MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, len))
return 0;
return 1;
}
}
9 changes: 8 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ function run_test((test_name, test_expected_outputs, expect_success), libblas_na
end
@test expected_return_value

# Expect to see the path to `libblastrampoline` within the output,
# since we have `LBT_VERBOSE=1` and at startup, it announces its own path:
if startswith(libblas_name, "blastrampoline")
lbt_libdir = first(libdirs)
@test occursin(lbt_libdir, output)
end

# Test to make sure the test ran properly
has_expected_output = all(occursin(expected, output) for expected in test_expected_outputs)
if !has_expected_output
Expand Down Expand Up @@ -187,7 +194,7 @@ end
if openblas_interface == :ILP64
inconsolable = ("inconsolable_test", ("||C||^2 is: 24.3384", "||b||^2 is: 3.0000"), true)
@testset "LBT -> OpenBLAS 32 + 64 (LP64 + ILP64)" begin
libdirs = unique(vcat(OpenBLAS32_jll.LIBPATH_list..., OpenBLAS_jll.LIBPATH_list..., CompilerSupportLibraries_jll.LIBPATH_list..., lbt_dir))
libdirs = unique(vcat(lbt_dir, OpenBLAS32_jll.LIBPATH_list..., OpenBLAS_jll.LIBPATH_list..., CompilerSupportLibraries_jll.LIBPATH_list...))
run_test(inconsolable, lbt_link_name, libdirs, :wild_sobbing, "$(OpenBLAS32_jll.libopenblas_path);$(OpenBLAS_jll.libopenblas_path)")
end
end
Expand Down

0 comments on commit 165da4c

Please sign in to comment.