Skip to content

Commit f1b7841

Browse files
Windows: undo cmakefile changes, use dll
1 parent bae40c8 commit f1b7841

File tree

2 files changed

+123
-13
lines changed

2 files changed

+123
-13
lines changed

libcxx/src/CMakeLists.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,6 @@ if (LIBCXX_ENABLE_SHARED)
254254
list(APPEND LIBCXX_BUILD_TARGETS "cxx_shared")
255255
endif()
256256

257-
if(WIN32)
258-
string(APPEND link_libraries " ${CMAKE_LINK_LIBRARY_FLAG}dbghelp")
259-
string(APPEND link_libraries " ${CMAKE_LINK_LIBRARY_FLAG}psapi")
260-
endif()
261-
262257
if(WIN32 AND NOT MINGW AND NOT "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
263258
# Since we most likely do not have a mt.exe replacement, disable the
264259
# manifest bundling. This allows a normal cmake invocation to pass which

libcxx/src/stacktrace/windows_impl.cpp

Lines changed: 123 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,126 @@
1919
# include <cstring>
2020
# include <mutex>
2121

22-
# if defined(_MSC_VER) && !defined(__MINGW32__)
23-
# pragma comment(lib, "dbghelp")
24-
# pragma comment(lib, "psapi")
25-
# endif
26-
2722
_LIBCPP_BEGIN_NAMESPACE_STD
2823
namespace __stacktrace {
2924

3025
namespace {
3126

27+
namespace __dll {
28+
29+
template <typename F>
30+
bool get_func(HMODULE module, F** func, char const* name) {
31+
return ((*func = reinterpret_cast<F*>(reinterpret_cast<void*>(GetProcAddress(module, name)))) != nullptr);
32+
}
33+
34+
IMAGE_NT_HEADERS* (*ImageNtHeader)(void*);
35+
bool(WINAPI* SymCleanup)(HANDLE);
36+
DWORD(WINAPI* SymGetOptions)();
37+
bool(WINAPI* SymGetSearchPath)(HANDLE, char const*, DWORD);
38+
bool(WINAPI* SymInitialize)(HANDLE, char const*, bool);
39+
DWORD(WINAPI* SymSetOptions)(DWORD);
40+
bool(WINAPI* SymSetSearchPath)(HANDLE, char const*);
41+
bool(WINAPI* EnumProcessModules)(HANDLE, HMODULE*, DWORD, DWORD*);
42+
bool(WINAPI* GetModuleInformation)(HANDLE, HMODULE, MODULEINFO*, DWORD);
43+
DWORD(WINAPI* GetModuleBaseName)(HANDLE, HMODULE, char**, DWORD);
44+
# ifdef _WIN64
45+
void*(WINAPI* SymFunctionTableAccess)(HANDLE, DWORD64);
46+
bool(WINAPI* SymGetLineFromAddr)(HANDLE, DWORD64, DWORD*, IMAGEHLP_LINE64*);
47+
DWORD64(WINAPI* SymGetModuleBase)(HANDLE, DWORD64);
48+
bool(WINAPI* SymGetModuleInfo)(HANDLE, DWORD64, IMAGEHLP_MODULE64*);
49+
bool(WINAPI* SymGetSymFromAddr)(HANDLE, DWORD64, DWORD64*, IMAGEHLP_SYMBOL64*);
50+
DWORD64(WINAPI* SymLoadModule)(HANDLE, HANDLE, char const*, char const*, void*, DWORD);
51+
bool(WINAPI* StackWalk)(
52+
DWORD,
53+
HANDLE,
54+
HANDLE,
55+
STACKFRAME64*,
56+
void*,
57+
void*,
58+
decltype(SymFunctionTableAccess),
59+
decltype(SymGetModuleBase),
60+
void*);
61+
# else
62+
void*(WINAPI* SymFunctionTableAccess)(HANDLE, DWORD);
63+
bool(WINAPI* SymGetLineFromAddr)(HANDLE, DWORD, DWORD*, IMAGEHLP_LINE*);
64+
DWORD(WINAPI* SymGetModuleBase)(HANDLE, DWORD);
65+
bool(WINAPI* SymGetModuleInfo)(HANDLE, DWORD, IMAGEHLP_MODULE*);
66+
bool(WINAPI* SymGetSymFromAddr)(HANDLE, DWORD, DWORD*, IMAGEHLP_SYMBOL*);
67+
DWORD(WINAPI* SymLoadModule)(HANDLE, HANDLE, char const*, char const*, void*, DWORD);
68+
bool(WINAPI* StackWalk)(
69+
DWORD,
70+
HANDLE,
71+
HANDLE,
72+
STACKFRAME*,
73+
void*,
74+
void*,
75+
decltype(SymFunctionTableAccess),
76+
decltype(SymGetModuleBase),
77+
void*);
78+
# endif
79+
80+
bool loadFuncs() {
81+
static bool attempted{false};
82+
static bool succeeded{false};
83+
static std::mutex mutex;
84+
85+
std::lock_guard<std::mutex> g(mutex);
86+
87+
if (succeeded) {
88+
return true;
89+
}
90+
if (attempted) {
91+
return false;
92+
}
93+
94+
attempted = true;
95+
96+
HMODULE dbghelp = LoadLibrary("dbghelp.dll");
97+
HMODULE psapi = LoadLibrary("psapi.dll");
98+
99+
// clang-format off
100+
succeeded = true
101+
&& (dbghelp != nullptr)
102+
&& (psapi != nullptr)
103+
&& get_func(dbghelp, &ImageNtHeader, "ImageNtHeader")
104+
&& get_func(dbghelp, &SymCleanup, "SymCleanup")
105+
&& get_func(dbghelp, &SymGetOptions, "SymGetOptions")
106+
&& get_func(dbghelp, &SymGetSearchPath, "SymGetSearchPath")
107+
&& get_func(dbghelp, &SymInitialize, "SymInitialize")
108+
&& get_func(dbghelp, &SymSetOptions, "SymSetOptions")
109+
&& get_func(dbghelp, &SymSetSearchPath, "SymSetSearchPath")
110+
&& get_func(psapi, &EnumProcessModules, "EnumProcessModules")
111+
&& get_func(psapi, &GetModuleInformation, "GetModuleInformation")
112+
&& get_func(psapi, &GetModuleBaseName, "GetModuleBaseNameA")
113+
#ifdef _WIN64
114+
&& get_func(dbghelp, &StackWalk, "StackWalk64")
115+
&& get_func(dbghelp, &SymFunctionTableAccess, "SymFunctionTableAccess64")
116+
&& get_func(dbghelp, &SymGetLineFromAddr, "SymGetLineFromAddr64")
117+
&& get_func(dbghelp, &SymGetModuleBase, "SymGetModuleBase64")
118+
&& get_func(dbghelp, &SymGetModuleInfo, "SymGetModuleInfo64")
119+
&& get_func(dbghelp, &SymGetSymFromAddr, "SymGetSymFromAddr64")
120+
&& get_func(dbghelp, &SymLoadModule, "SymLoadModule64")
121+
#else
122+
&& get_func(dbghelp, &StackWalk, "StackWalk")
123+
&& get_func(dbghelp, &SymFunctionTableAccess, "SymFunctionTableAccess")
124+
&& get_func(dbghelp, &SymGetLineFromAddr, "SymGetLineFromAddr")
125+
&& get_func(dbghelp, &SymGetModuleBase, "SymGetModuleBase")
126+
&& get_func(dbghelp, &SymGetModuleInfo, "SymGetModuleInfo")
127+
&& get_func(dbghelp, &SymGetSymFromAddr, "SymGetSymFromAddr")
128+
&& get_func(dbghelp, &SymLoadModule, "SymLoadModule")
129+
#endif
130+
;
131+
// clang-format on
132+
133+
FreeLibrary(psapi);
134+
FreeLibrary(dbghelp);
135+
return succeeded;
136+
}
137+
138+
} // namespace __dll
139+
140+
using namespace __dll;
141+
32142
struct _Sym_Init_Scope {
33143
HANDLE proc_;
34144

@@ -39,6 +149,11 @@ struct _Sym_Init_Scope {
39149
} // namespace
40150

41151
_LIBCPP_EXPORTED_FROM_ABI void _Trace::windows_impl(size_t skip, size_t max_depth) {
152+
static bool loadedDLLFuncs = loadFuncs();
153+
if (!loadedDLLFuncs) {
154+
return;
155+
}
156+
42157
if (!max_depth) {
43158
return;
44159
}
@@ -171,11 +286,11 @@ _LIBCPP_EXPORTED_FROM_ABI void _Trace::windows_impl(size_t skip, size_t max_dept
171286
sym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
172287
sym->MaxNameLength = __max_sym_len;
173288
# if defined(_WIN64)
174-
DWORD64 symdisp;
289+
DWORD64 symdisp{};
175290
# else
176-
DWORD32 symdisp;
291+
DWORD symdisp{};
177292
# endif
178-
DWORD linedisp{0};
293+
DWORD linedisp{};
179294
IMAGEHLP_LINE line;
180295
if (SymGetSymFromAddr(proc, entry.__addr_, &symdisp, sym)) {
181296
entry.__desc_.assign(sym->Name);

0 commit comments

Comments
 (0)