Skip to content

Commit 41c1490

Browse files
authored
Add an event log message when loading hostfxr fails (#6670)
1 parent b56c589 commit 41c1490

File tree

8 files changed

+89
-31
lines changed

8 files changed

+89
-31
lines changed

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,7 @@ try
214214
DWORD dwBufferSize = s_initialGetNativeSearchDirectoriesBufferSize;
215215
DWORD dwRequiredBufferSize = 0;
216216

217-
RETURN_LAST_ERROR_IF_NULL(m_hHostFxrDll = LoadLibraryW(hostfxrOptions.GetHostFxrLocation().c_str()));
218-
219-
auto const hostFxr = HostFxr::CreateFromLoadedModule();
217+
m_hHostFxrDll.Load(hostfxrOptions.GetHostFxrLocation());
220218

221219
{
222220
auto redirectionOutput = LoggingHelpers::CreateOutputs(
@@ -227,7 +225,7 @@ try
227225
);
228226

229227
StandardStreamRedirection stdOutRedirection(*redirectionOutput.get(), m_pServer.IsCommandLineLaunch());
230-
auto hostFxrErrorRedirection = hostFxr.RedirectOutput(redirectionOutput.get());
228+
auto hostFxrErrorRedirection = m_hHostFxrDll.RedirectOutput(redirectionOutput.get());
231229

232230
struNativeSearchPaths.resize(dwBufferSize);
233231
while (TRUE)
@@ -237,7 +235,7 @@ try
237235

238236
hostfxrOptions.GetArguments(hostfxrArgc, hostfxrArgv);
239237

240-
const auto intHostFxrExitCode = hostFxr.GetNativeSearchDirectories(
238+
const auto intHostFxrExitCode = m_hHostFxrDll.GetNativeSearchDirectories(
241239
hostfxrArgc,
242240
hostfxrArgv.get(),
243241
struNativeSearchPaths.data(),

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "HandleWrapper.h"
1111
#include "ApplicationFactory.h"
1212
#include "RedirectionOutput.h"
13+
#include "HostFxr.h"
1314

1415
class HandlerResolver
1516
{
@@ -35,7 +36,7 @@ class HandlerResolver
3536
SRWLOCK m_requestHandlerLoadLock {};
3637
std::wstring m_loadedApplicationId;
3738
APP_HOSTING_MODEL m_loadedApplicationHostingModel;
38-
HandleWrapper<ModuleHandleTraits> m_hHostFxrDll;
39+
HostFxr m_hHostFxrDll;
3940

4041
static const PCWSTR s_pwzAspnetcoreInProcessRequestHandlerName;
4142
static const PCWSTR s_pwzAspnetcoreOutOfProcessRequestHandlerName;

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxr.cpp

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,41 +30,72 @@ void HostFxrErrorRedirector::HostFxrErrorRedirectorCallback(const WCHAR* message
3030
m_writeFunction->Append(std::wstring(message) + L"\r\n");
3131
}
3232

33-
int HostFxr::Main(DWORD argc, const PCWSTR* argv) const noexcept(false)
34-
{
35-
return m_hostfxr_main_fn(argc, argv);
36-
}
3733

38-
int HostFxr::GetNativeSearchDirectories(INT argc, const PCWSTR* argv, PWSTR buffer, DWORD buffer_size, DWORD* required_buffer_size) const noexcept
34+
void HostFxr::Load()
3935
{
40-
return m_hostfxr_get_native_search_directories_fn(argc, argv, buffer, buffer_size, required_buffer_size);
36+
HMODULE hModule;
37+
THROW_LAST_ERROR_IF(!GetModuleHandleEx(0, L"hostfxr.dll", &hModule));
38+
Load(hModule);
4139
}
4240

43-
HostFxrErrorRedirector HostFxr::RedirectOutput(RedirectionOutput* writer) const noexcept
41+
void HostFxr::Load(HMODULE moduleHandle)
4442
{
45-
return HostFxrErrorRedirector(m_corehost_set_error_writer_fn, writer);
43+
m_hHostFxrDll = moduleHandle;
44+
try
45+
{
46+
m_hostfxr_main_fn = ModuleHelpers::GetKnownProcAddress<hostfxr_main_fn>(moduleHandle, "hostfxr_main");
47+
m_hostfxr_get_native_search_directories_fn = ModuleHelpers::GetKnownProcAddress<hostfxr_get_native_search_directories_fn>(moduleHandle, "hostfxr_get_native_search_directories");
48+
m_corehost_set_error_writer_fn = ModuleHelpers::GetKnownProcAddress<corehost_set_error_writer_fn>(moduleHandle, "hostfxr_set_error_writer", /* optional */ true);
49+
}
50+
catch (...)
51+
{
52+
EventLog::Error(
53+
ASPNETCORE_EVENT_GENERAL_ERROR,
54+
ASPNETCORE_EVENT_HOSTFXR_DLL_INVALID_VERSION_MSG,
55+
ModuleHelpers::GetModuleFileNameValue(moduleHandle).c_str()
56+
);
57+
58+
throw;
59+
}
4660
}
4761

48-
HostFxr HostFxr::CreateFromLoadedModule()
49-
{
50-
HMODULE hModule;
51-
THROW_LAST_ERROR_IF_NULL(hModule = GetModuleHandle(L"hostfxr.dll"));
5262

63+
void HostFxr::Load(const std::wstring& location)
64+
{
5365
try
5466
{
55-
return HostFxr(
56-
ModuleHelpers::GetKnownProcAddress<hostfxr_main_fn>(hModule, "hostfxr_main"),
57-
ModuleHelpers::GetKnownProcAddress<hostfxr_get_native_search_directories_fn>(hModule, "hostfxr_get_native_search_directories"),
58-
ModuleHelpers::GetKnownProcAddress<corehost_set_error_writer_fn>(hModule, "hostfxr_set_error_writer", /* optional */ true));
67+
HMODULE hModule;
68+
THROW_LAST_ERROR_IF_NULL(hModule = LoadLibraryW(location.c_str()));
69+
Load(hModule);
5970
}
6071
catch (...)
6172
{
6273
EventLog::Error(
6374
ASPNETCORE_EVENT_GENERAL_ERROR,
64-
ASPNETCORE_EVENT_HOSTFXR_DLL_INVALID_VERSION_MSG,
65-
ModuleHelpers::GetModuleFileNameValue(hModule).c_str()
75+
ASPNETCORE_EVENT_HOSTFXR_DLL_UNABLE_TO_LOAD_MSG,
76+
location.c_str()
6677
);
6778

6879
throw;
6980
}
7081
}
82+
83+
void HostFxr::SetMain(hostfxr_main_fn hostfxr_main_fn)
84+
{
85+
m_hostfxr_main_fn = hostfxr_main_fn;
86+
}
87+
88+
int HostFxr::Main(DWORD argc, const PCWSTR* argv) const noexcept(false)
89+
{
90+
return m_hostfxr_main_fn(argc, argv);
91+
}
92+
93+
int HostFxr::GetNativeSearchDirectories(INT argc, const PCWSTR* argv, PWSTR buffer, DWORD buffer_size, DWORD* required_buffer_size) const noexcept
94+
{
95+
return m_hostfxr_get_native_search_directories_fn(argc, argv, buffer, buffer_size, required_buffer_size);
96+
}
97+
98+
HostFxrErrorRedirector HostFxr::RedirectOutput(RedirectionOutput* writer) const noexcept
99+
{
100+
return HostFxrErrorRedirector(m_corehost_set_error_writer_fn, writer);
101+
}

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxr.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@ class HostFxrErrorRedirector: NonCopyable
2626
static inline thread_local RedirectionOutput* m_writeFunction;
2727
};
2828

29-
class HostFxr
29+
class HostFxr: NonCopyable
3030
{
3131
public:
32+
HostFxr() : HostFxr(nullptr, nullptr, nullptr)
33+
{
34+
}
35+
3236
HostFxr(
3337
hostfxr_main_fn hostfxr_main_fn,
3438
hostfxr_get_native_search_directories_fn hostfxr_get_native_search_directories_fn,
@@ -39,18 +43,22 @@ class HostFxr
3943
{
4044
}
4145

46+
void Load();
47+
void Load(HMODULE moduleHandle);
48+
void Load(const std::wstring& location);
49+
4250
~HostFxr() = default;
4351

52+
void SetMain(hostfxr_main_fn hostfxr_main_fn);
53+
4454
int Main(DWORD argc, CONST PCWSTR* argv) const noexcept(false);
4555

4656
int GetNativeSearchDirectories(INT argc, CONST PCWSTR* argv, PWSTR buffer, DWORD buffer_size, DWORD* required_buffer_size) const noexcept;
4757

4858
HostFxrErrorRedirector RedirectOutput(RedirectionOutput* writer) const noexcept;
4959

50-
static
51-
HostFxr CreateFromLoadedModule();
52-
5360
private:
61+
HandleWrapper<ModuleHandleTraits> m_hHostFxrDll;
5462
hostfxr_main_fn m_hostfxr_main_fn;
5563
hostfxr_get_native_search_directories_fn m_hostfxr_get_native_search_directories_fn;
5664
corehost_set_error_writer_fn m_corehost_set_error_writer_fn;

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/resources.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#define ASPNETCORE_EVENT_RECYCLE_FAILURE_CONFIGURATION_MSG L"Failed to recycle application due to a configuration change at '%s'. Recycling worker process."
4040
#define ASPNETCORE_EVENT_MODULE_DISABLED_MSG L"AspNetCore Module is disabled"
4141
#define ASPNETCORE_EVENT_HOSTFXR_DLL_INVALID_VERSION_MSG L"Hostfxr version used does not support 'hostfxr_get_native_search_directories', update the version of hostfxr to a higher version. Path to hostfxr: '%s'."
42+
#define ASPNETCORE_EVENT_HOSTFXR_DLL_UNABLE_TO_LOAD_MSG L"Unable to load '%s'. This might be caused by a bitness mismatch between IIS application pool and published application."
4243
#define ASPNETCORE_EVENT_HOSTFXR_FAILURE_MSG L"Invoking hostfxr to find the inprocess request handler failed without finding any native dependencies. This most likely means the app is misconfigured, please check the versions of Microsoft.NetCore.App and Microsoft.AspNetCore.App that are targeted by the application and are installed on the machine."
4344
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXCEPTION_MSG L"Application '%s' with physical root '%s' hit unexpected managed exception, exception code = '0x%x'. Please check the stderr logs for more information."
4445
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXCEPTION_STDOUT_MSG L"Application '%s' with physical root '%s' hit unexpected managed exception, exception code = '0x%x'. Last 4KB characters of captured stdout and stderr logs:\r\n%s"

src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,11 @@ IN_PROCESS_APPLICATION::ExecuteApplication()
189189

190190
hostFxrResolutionResult->GetArguments(context->m_argc, context->m_argv);
191191
THROW_IF_FAILED(SetEnvironmentVariablesOnWorkerProcess());
192-
context->m_hostFxr = HostFxr::CreateFromLoadedModule();
192+
context->m_hostFxr.Load();
193193
}
194194
else
195195
{
196-
context->m_hostFxr = HostFxr(s_fMainCallback, nullptr, nullptr);
196+
context->m_hostFxr.SetMain(s_fMainCallback);
197197
}
198198

199199
// There can only ever be a single instance of .NET Core

src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ public async Task LogsUnexpectedThreadExitError()
257257
}
258258

259259
[ConditionalFact]
260-
public async Task RemoveHostfxrFromApp_InProcessHostfxrInvalid()
260+
public async Task RemoveHostfxrFromApp_InProcessHostfxrAPIAbsent()
261261
{
262262
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
263263
deploymentParameters.ApplicationType = ApplicationType.Standalone;
@@ -272,6 +272,20 @@ public async Task RemoveHostfxrFromApp_InProcessHostfxrInvalid()
272272
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessHostfxrInvalid(deploymentResult), Logger);
273273
}
274274

275+
[ConditionalFact]
276+
public async Task RemoveHostfxrFromApp_InProcessHostfxrLoadFailure()
277+
{
278+
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
279+
deploymentParameters.ApplicationType = ApplicationType.Standalone;
280+
var deploymentResult = await DeployAsync(deploymentParameters);
281+
282+
// We don't distinguish between load failure types so making dll empty should be enough
283+
File.WriteAllText(Path.Combine(deploymentResult.ContentRoot, "hostfxr.dll"), "");
284+
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
285+
286+
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessHostfxrUnableToLoad(deploymentResult), Logger);
287+
}
288+
275289
[ConditionalFact]
276290
public async Task TargedDifferenceSharedFramework_FailedToFindNativeDependencies()
277291
{

src/Servers/IIS/IIS/test/Common.FunctionalTests/Utilities/EventLogHelpers.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ public static string InProcessHostfxrInvalid(IISDeploymentResult deploymentResul
185185
return $"Hostfxr version used does not support 'hostfxr_get_native_search_directories', update the version of hostfxr to a higher version. Path to hostfxr: '(.*)'.";
186186
}
187187

188+
public static string InProcessHostfxrUnableToLoad(IISDeploymentResult deploymentResult)
189+
{
190+
return $"Unable to load '(.*)'. This might be caused by a bitness mismatch between IIS application pool and published application.";
191+
}
192+
188193
public static string InProcessFailedToFindNativeDependencies(IISDeploymentResult deploymentResult)
189194
{
190195
return "Invoking hostfxr to find the inprocess request handler failed without finding any native dependencies. " +

0 commit comments

Comments
 (0)