<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/91248>91248</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Registering Clang plugins on Windows does not work due to different pointers for FrontendPluginRegistry::Head
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
hach-que
</td>
</tr>
</table>
<pre>
I built my own version of Clang for Windows that provides the `lib\clang...lib` files for Windows, and then built a Clang plugin against it.
The typical definition doesn't work:
```cpp
static FrontendPluginRegistry::Add<redpoint::AlwaysBeforeAction> X3("redpoint-namespace-warnings", "");
```
so instead I tried registering it through DllMain which *does* successfully run, but the linked lists for `FrontendPluginRegistry` end up different:
```cpp
static FrontendPluginRegistry::Add<redpoint::AlwaysBeforeAction>* RedpointPluginInstance = nullptr;
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved) // reserved
{
// Perform actions based on the reason for calling.
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
printf("dll loaded!\n");
{
if (RedpointPluginInstance == nullptr)
{
printf("registering plugin...\n");
RedpointPluginInstance = new FrontendPluginRegistry::Add<redpoint::AlwaysBeforeAction>("redpoint-namespace-warnings", "");
}
for (const FrontendPluginRegistry::entry& Plugin :
FrontendPluginRegistry::entries()) {
printf("plugin: %s\n", Plugin.getName().str().c_str());
}
}
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
printf("dll thread attach!\n");
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
printf("dll thread detach!\n");
break;
case DLL_PROCESS_DETACH:
printf("dll unloaded!\n");
if (lpvReserved != nullptr)
{
break; // do not do cleanup if process termination scenario
}
// Perform any necessary cleanup.
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
```
I modified `LLVM_INSTANTIATE_REGISTRY` to print out the locations of `Head` and `Tail`:
```cpp
#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
namespace llvm { \
template<typename T> typename Registry<T>::node *Registry<T>::Head = nullptr;\
template<typename T> typename Registry<T>::node *Registry<T>::Tail = nullptr;\
template<typename T> \
void Registry<T>::add_node(typename Registry<T>::node *N) { \
printf("add_node Registry<" #REGISTRY_CLASS ">::Head = (& %p) (v %p)\n", &Head, Head); \
printf("add_node Registry<" #REGISTRY_CLASS ">::Tail = (& %p) (v %p)\n", &Tail, Tail); \
if (Tail) \
Tail->Next = N; \
else \
Head = N; \
Tail = N; \
} \
template<typename T> typename Registry<T>::iterator Registry<T>::begin() { \
printf("begin &Registry<" #REGISTRY_CLASS ">::Head = (& %p) (v %p)\n", &Head, Head);\
printf("begin &Registry<" #REGISTRY_CLASS ">::Tail = (& %p) (v %p)\n", &Tail, Tail);\
return iterator(Head); \
} \
template REGISTRY_CLASS::node *Registry<REGISTRY_CLASS::type>::Head; \
template REGISTRY_CLASS::node *Registry<REGISTRY_CLASS::type>::Tail; \
template \
void Registry<REGISTRY_CLASS::type>::add_node(REGISTRY_CLASS::node*); \
template REGISTRY_CLASS::iterator Registry<REGISTRY_CLASS::type>::begin(); \
}
```
Running Clang with the plugin, then gives the following output:
```
-fplugin=C:\Work\clang-plugins-demo\buildmsvc\lib\Release\streamchecker.dll -Xclang -plugin -Xclang redpoint-namespace-warnings main.cpp -fsyntax-only
add_node Registry<GCRegistry>::Head = (& 00007FF773911230) (v 0000000000000000)
add_node Registry<GCRegistry>::Tail = (& 00007FF773911238) (v 0000000000000000)
add_node Registry<GCRegistry>::Head = (& 00007FF773911230) (v 00007FF77388DD40)
add_node Registry<GCRegistry>::Tail = (& 00007FF773911238) (v 00007FF77388DD40)
add_node Registry<GCRegistry>::Head = (& 00007FF773911230) (v 00007FF77388DD40)
add_node Registry<GCRegistry>::Tail = (& 00007FF773911238) (v 00007FF77388DD78)
add_node Registry<GCRegistry>::Head = (& 00007FF773911230) (v 00007FF77388DD40)
add_node Registry<GCRegistry>::Tail = (& 00007FF773911238) (v 00007FF77388DDB0)
add_node Registry<GCRegistry>::Head = (& 00007FF773911230) (v 00007FF77388DD40)
add_node Registry<GCRegistry>::Tail = (& 00007FF773911238) (v 00007FF77388DDE8)
Plugin to load: C:\Work\clang-plugins-demo\buildmsvc\lib\Release\streamchecker.dll
add_node Registry<GCRegistry>::Head = (& 00007FF93A49EB50) (v 0000000000000000)
add_node Registry<GCRegistry>::Tail = (& 00007FF93A49EB58) (v 0000000000000000)
add_node Registry<GCRegistry>::Head = (& 00007FF93A49EB50) (v 00007FF93A48D0B0)
add_node Registry<GCRegistry>::Tail = (& 00007FF93A49EB58) (v 00007FF93A48D0B0)
add_node Registry<GCRegistry>::Head = (& 00007FF93A49EB50) (v 00007FF93A48D0B0)
add_node Registry<GCRegistry>::Tail = (& 00007FF93A49EB58) (v 00007FF93A48D0E8)
add_node Registry<GCRegistry>::Head = (& 00007FF93A49EB50) (v 00007FF93A48D0B0)
add_node Registry<GCRegistry>::Tail = (& 00007FF93A49EB58) (v 00007FF93A48D120)
add_node Registry<GCRegistry>::Head = (& 00007FF93A49EB50) (v 00007FF93A48D0B0)
add_node Registry<GCRegistry>::Tail = (& 00007FF93A49EB58) (v 00007FF93A48D158)
dll loaded!
registering plugin...
add_node Registry<FrontendPluginRegistry>::Head = (& 00007FF93A493C48) (v 0000000000000000)
add_node Registry<FrontendPluginRegistry>::Tail = (& 00007FF93A493C50) (v 0000000000000000)
begin &Registry<FrontendPluginRegistry>::Head = (& 00007FF93A493C48) (v 000001BC2E2BDAE8)
begin &Registry<FrontendPluginRegistry>::Tail = (& 00007FF93A493C50) (v 000001BC2E2BDAE8)
plugin: redpoint-namespace-warnings
begin &Registry<FrontendPluginRegistry>::Head = (& 00007FF773920540) (v 0000000000000000)
begin &Registry<FrontendPluginRegistry>::Tail = (& 00007FF773920548) (v 0000000000000000)
begin &Registry<FrontendPluginRegistry>::Head = (& 00007FF773920540) (v 0000000000000000)
begin &Registry<FrontendPluginRegistry>::Tail = (& 00007FF773920548) (v 0000000000000000)
error: unable to find plugin 'redpoint-namespace-warnings'
dll unloaded!
```
I believe this is because `LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry)` is in `clangFrontend.lib`, and then:
- `clang.exe` gets a copy of it when it's compiled.
- `streamchecker.dll` gets a copy of it when it's compiled.
The option `BUILD_SHARED_LIBS` isn't available on Windows, which would presumably otherwise produce `clangFrontend.dll` which both `clang.exe` and `streamchecker.dll` could share.
I believe there's two ways to fix this:
1. Get `BUILD_SHARED_LIBS` working on Windows so that it produces DLL files, or
2. Pass a function pointer to a known function name (like `CheckerMatcher` or `lldb`), where the provided function calls `add_node` to the real `FrontendPluginRegistry` on the plugin's behalf, e.g.
```cpp
bool success = false;
plugin_info.plugin_init_callback = CastToFPtr<PluginInitCallback>(
plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"));
if (plugin_info.plugin_init_callback) {
// Call the plug-in "bool LLDBPluginInitialize(void)" function
success = plugin_info.plugin_init_callback();
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzkGtlu4zjya5iXgg2Zjq-HPDiyMx3Akw4cz_TsU0BLJYsbmtSSlN3er1-QOqz4Sro7PRj0BoF1kKy7iqUqMmP4SiLekN4t6U2uWG5TpW9SFqWt_-R4tVTx7uYeljkXFtY7UFsJG9SGKwkqgVAwuYJEafjCZay2BmzKLGRabXiM7gmB9APBl6QXRm5yu912T_0AEi7QNNcSGgKTsVskS4ysxJCJfMUlsBXj0ljgtk2CCQnGxe8iRbC7jEdMQIwJl9w6-mKFRhI6sLBV-oV0x801pB8U_1GWFW-MZZZHcKeVtCjjR49yjiturN651d3xOI5JN9QYZ4pLW74TW7Yzt5gojePIISbdKfzVJXRIKK3mtiRbo8lYhK0t05LLlSGUOo79hRI6It3bA9Ka9BoFjnVkMdyD1Rxj0J421FyugFuwqVb5KoWJEL8zLmGb8igFQsdODoSOweRRhMYkuRA70Ll02Je59UoSXL5gDIIbW-iE9IMzkugHgDKGPIOYJwlqLCTxt8nWsTIvpxWA7qWxTEYIpDsBmQuRWb2Xpv-9_fx5Bl_uH8aP95WAnILKGaNP9w9Pi_FDOIXUSXkymznhAKF3hN5BymQsEKyCyWwGaxXnAuulky-f5xNI4u0cmVFeqO6vXKr9Sy_RiAnhVJXksmClgjB7_PPz_QREtpmjQb3BmNBRA0L5rpg-qNkalRMeUSdKr4F5qAaWzGAMSnq9HuOvPWdkttx6Cxk2qB_twTdQRcygY_75cf45nD49PY8Xi3H4qaH30Z6ge-d_TPD_IiinFYccWZSCxK0LDc4I2yfWzdHmWsLdePY0dcJOGBde4kKx-NWCTHNpk8LDYiH8BCe1DumF8tCbChSD14_BiCeO8_OG1LSlplTOgDugqumbRfBqt9vnqfP_l4watx_lPN8dlfa8Tw7e-HhBh5FysfkSmSjdLe1DMQiH9uP_3wLAXTQbOtLoCN5URCF80h0DoT1TayAsSWiv0D6wNRYQ28Yp299Fz_X9u6Tw-nGpkb0chKCmGy0-zafjyUUvmigX0ZHFLZNhxBMeAa8cizltXvSIYikwa1mUXnKMd1I6mX4TpZFAJvPsPSTG-KMkVjHpJI2HWHN5OVjsVxYBohGVwa05HxWOLLGiu4rksQKprLuU4gGeVPEQLOo1l16xYCKUTHN1xsCOFFDvAHIHEh04pncndXAoyld2q4v4u5j_MXVUV2Q_1WnDiR2ggl6DOZW73Ls9kycuZyH9YDb78_fnYr9d3I8X0-f59Lf7p8X8Xy6zsAq8xkBViYmKWLGvqcSt_oQsdhNdokj6wYJx4bC9lYAQ2vWZIcJ59HRY3T6Hs_HTk48vvbAAAFDHShBis3aRpzFqcZ0JZpF0Q7vL0M2FhUsE66d9IAvdQBHPpIrRpWgnBx2rhynNnpyfgdFJ8zswNuZsFI9PI2Zx_OyQEzp8H4UPZXxvgG86cwWvCYRQCoR2X6vR72VHMvVA-m5TyDweOtxUD41NgtC-NzgaQnEdeX_e8wsfQFMt9XfT5K2ehlBcj2kqQlc52hhyb1qkO33Ar9ZjfDhaisLg6zcAtdCOp9e0Hw6RwQR-3Fq5Rc2s0qdHl7gq0vgjQznQi5_oBPe328oHk_QRpvKKpDLmV3ImdHjazs-oEw4i5rkQc2qa0_wrWR-g_HAcXgRncFwIYW_CbUS2c6QSOj6W6UUGT1n-m5Q0HOJYfxc26HkuXfJfFlu23KZ-7y1zZxoWJZkV35QlnUQJobZuhcptlp_9_i8eW0mVhE9CN7MXflH6pSoItYpB04pxrUgvXOZcxGuziUgvLOpGcxTIDJJeaKxGto5SjF5Qt1061_rLA4ESSv184QsH1ozLdpRl0ErMTlr2taWk2DUZOBXHfwv3D2cCRBAEweDubjDojjod2g1qzwwO_urU8Z2IDt3-ANHwwxB9E0fFwHA4mVz_XI5-BNE_naPB8Ffj6PaX09F0r6OycGGVrzmR7hg-OqR9hORG3fH1aHrb--kRqEL00yPQaY7KgeEk-Haj-yaOfgTRP52j6UdFoH8KRx36q-mo09vr6HW92786XWw-S9a5Aus7ZNENr7_T1d9Aekku3fA9gezUB9WHctq5DemU3k7GDYf5DqTfxukppPuS9qU6_gcLxe2RNOhd_xxNXNiYHdJ32Nz_D6eotdJO-7lky6ItmXAZVz1yQgcX2zuDfRhp1sIvVW-XKDhuEGzKDXADS4xYbvByMZcOz0iCjkg_cGAcsf3AZ0zV1PJsQPMkQP1t2apnt_ErOhgrtAYYRCrbgUqAW9i671RuCR0YiNQ64wKrzqFffpxtfSuY4neRIqjMF-tJP7j94342eX76NJ5PJ8-z-9ungsHi7AHbMC68opRsnnQo2vNblYsYMo0mX7Ol2IGyKeotNwiZVnEe4bGMSrILAEtl0yPBlMXxk9xGHqNJmcb2OTWjRs-73SrYsp0pbOyrN4BaH502_Ib2LP9bpV98haDmGowqjodwWzFnfH_XnwRxMlG6AE3b8MiMU0rVLAdv0KgdJQxepNrK_ZivHxI6FPzFiyssOP6d2ShF7YgpDjQIERfWNSoUgBqLOkdxXCXeQ4yYEMYtqWs7RW-ibKmLy8cjyt57VT4ZOI9JmUgcVmxXHXh_SuCoUeHeLpUS1WkNHysSJgzWbZsS8DOXiWrX99w-O6qXLHrxa0Jm7ELdPVpNumHVUuY2LOeUveBjgIIvNdO79grtOI41GvM5edqtl0oUhcvZbHK7B1f0-csuWqORtq9Cv0Xsqy4uNM9OOFJrQbZ8aKNeNKdJGG4U95VLSg_OWBRQmwJ9m6jhITd1Be2V3q7im2486o7YFd50Bp1e0Bn2BvQqvYk6EUaMYtCLh_3ldUB7o148DEajzjLusl7_it_QgF4HvaDfGQa0F7Q7y2UvCOIRG_bj0TAZkusA14yLthCbdVvp1RU3JsebUYdeD68EW6Iw_tgWpd75nRJ6kyt94-a3lvnKkOvAH-jZQ7DcCryZN_LF5vkq03TWWKHx_UrnyBDnfqOpT_xU_lgcFrrUsne77FWuxU1qbeajh9fuits0X7YjtSb0ztFXXlqZVv_GyBJ659k1hN55jv8XAAD__9QEHw0">