Add an event log message when loading hostfxr fails (#6670)

This commit is contained in:
Pavel Krymets 2019-01-15 15:07:51 -08:00 committed by GitHub
parent b56c589773
commit 41c1490468
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 95 additions and 37 deletions

View File

@ -214,9 +214,7 @@ try
DWORD dwBufferSize = s_initialGetNativeSearchDirectoriesBufferSize;
DWORD dwRequiredBufferSize = 0;
RETURN_LAST_ERROR_IF_NULL(m_hHostFxrDll = LoadLibraryW(hostfxrOptions.GetHostFxrLocation().c_str()));
auto const hostFxr = HostFxr::CreateFromLoadedModule();
m_hHostFxrDll.Load(hostfxrOptions.GetHostFxrLocation());
{
auto redirectionOutput = LoggingHelpers::CreateOutputs(
@ -227,7 +225,7 @@ try
);
StandardStreamRedirection stdOutRedirection(*redirectionOutput.get(), m_pServer.IsCommandLineLaunch());
auto hostFxrErrorRedirection = hostFxr.RedirectOutput(redirectionOutput.get());
auto hostFxrErrorRedirection = m_hHostFxrDll.RedirectOutput(redirectionOutput.get());
struNativeSearchPaths.resize(dwBufferSize);
while (TRUE)
@ -237,7 +235,7 @@ try
hostfxrOptions.GetArguments(hostfxrArgc, hostfxrArgv);
const auto intHostFxrExitCode = hostFxr.GetNativeSearchDirectories(
const auto intHostFxrExitCode = m_hHostFxrDll.GetNativeSearchDirectories(
hostfxrArgc,
hostfxrArgv.get(),
struNativeSearchPaths.data(),

View File

@ -10,6 +10,7 @@
#include "HandleWrapper.h"
#include "ApplicationFactory.h"
#include "RedirectionOutput.h"
#include "HostFxr.h"
class HandlerResolver
{
@ -35,7 +36,7 @@ private:
SRWLOCK m_requestHandlerLoadLock {};
std::wstring m_loadedApplicationId;
APP_HOSTING_MODEL m_loadedApplicationHostingModel;
HandleWrapper<ModuleHandleTraits> m_hHostFxrDll;
HostFxr m_hHostFxrDll;
static const PCWSTR s_pwzAspnetcoreInProcessRequestHandlerName;
static const PCWSTR s_pwzAspnetcoreOutOfProcessRequestHandlerName;

View File

@ -30,6 +30,61 @@ void HostFxrErrorRedirector::HostFxrErrorRedirectorCallback(const WCHAR* message
m_writeFunction->Append(std::wstring(message) + L"\r\n");
}
void HostFxr::Load()
{
HMODULE hModule;
THROW_LAST_ERROR_IF(!GetModuleHandleEx(0, L"hostfxr.dll", &hModule));
Load(hModule);
}
void HostFxr::Load(HMODULE moduleHandle)
{
m_hHostFxrDll = moduleHandle;
try
{
m_hostfxr_main_fn = ModuleHelpers::GetKnownProcAddress<hostfxr_main_fn>(moduleHandle, "hostfxr_main");
m_hostfxr_get_native_search_directories_fn = ModuleHelpers::GetKnownProcAddress<hostfxr_get_native_search_directories_fn>(moduleHandle, "hostfxr_get_native_search_directories");
m_corehost_set_error_writer_fn = ModuleHelpers::GetKnownProcAddress<corehost_set_error_writer_fn>(moduleHandle, "hostfxr_set_error_writer", /* optional */ true);
}
catch (...)
{
EventLog::Error(
ASPNETCORE_EVENT_GENERAL_ERROR,
ASPNETCORE_EVENT_HOSTFXR_DLL_INVALID_VERSION_MSG,
ModuleHelpers::GetModuleFileNameValue(moduleHandle).c_str()
);
throw;
}
}
void HostFxr::Load(const std::wstring& location)
{
try
{
HMODULE hModule;
THROW_LAST_ERROR_IF_NULL(hModule = LoadLibraryW(location.c_str()));
Load(hModule);
}
catch (...)
{
EventLog::Error(
ASPNETCORE_EVENT_GENERAL_ERROR,
ASPNETCORE_EVENT_HOSTFXR_DLL_UNABLE_TO_LOAD_MSG,
location.c_str()
);
throw;
}
}
void HostFxr::SetMain(hostfxr_main_fn hostfxr_main_fn)
{
m_hostfxr_main_fn = hostfxr_main_fn;
}
int HostFxr::Main(DWORD argc, const PCWSTR* argv) const noexcept(false)
{
return m_hostfxr_main_fn(argc, argv);
@ -44,27 +99,3 @@ HostFxrErrorRedirector HostFxr::RedirectOutput(RedirectionOutput* writer) const
{
return HostFxrErrorRedirector(m_corehost_set_error_writer_fn, writer);
}
HostFxr HostFxr::CreateFromLoadedModule()
{
HMODULE hModule;
THROW_LAST_ERROR_IF_NULL(hModule = GetModuleHandle(L"hostfxr.dll"));
try
{
return HostFxr(
ModuleHelpers::GetKnownProcAddress<hostfxr_main_fn>(hModule, "hostfxr_main"),
ModuleHelpers::GetKnownProcAddress<hostfxr_get_native_search_directories_fn>(hModule, "hostfxr_get_native_search_directories"),
ModuleHelpers::GetKnownProcAddress<corehost_set_error_writer_fn>(hModule, "hostfxr_set_error_writer", /* optional */ true));
}
catch (...)
{
EventLog::Error(
ASPNETCORE_EVENT_GENERAL_ERROR,
ASPNETCORE_EVENT_HOSTFXR_DLL_INVALID_VERSION_MSG,
ModuleHelpers::GetModuleFileNameValue(hModule).c_str()
);
throw;
}
}

View File

@ -26,9 +26,13 @@ private:
static inline thread_local RedirectionOutput* m_writeFunction;
};
class HostFxr
class HostFxr: NonCopyable
{
public:
HostFxr() : HostFxr(nullptr, nullptr, nullptr)
{
}
HostFxr(
hostfxr_main_fn hostfxr_main_fn,
hostfxr_get_native_search_directories_fn hostfxr_get_native_search_directories_fn,
@ -39,18 +43,22 @@ public:
{
}
void Load();
void Load(HMODULE moduleHandle);
void Load(const std::wstring& location);
~HostFxr() = default;
void SetMain(hostfxr_main_fn hostfxr_main_fn);
int Main(DWORD argc, CONST PCWSTR* argv) const noexcept(false);
int GetNativeSearchDirectories(INT argc, CONST PCWSTR* argv, PWSTR buffer, DWORD buffer_size, DWORD* required_buffer_size) const noexcept;
HostFxrErrorRedirector RedirectOutput(RedirectionOutput* writer) const noexcept;
static
HostFxr CreateFromLoadedModule();
private:
HandleWrapper<ModuleHandleTraits> m_hHostFxrDll;
hostfxr_main_fn m_hostfxr_main_fn;
hostfxr_get_native_search_directories_fn m_hostfxr_get_native_search_directories_fn;
corehost_set_error_writer_fn m_corehost_set_error_writer_fn;

View File

@ -39,6 +39,7 @@
#define ASPNETCORE_EVENT_RECYCLE_FAILURE_CONFIGURATION_MSG L"Failed to recycle application due to a configuration change at '%s'. Recycling worker process."
#define ASPNETCORE_EVENT_MODULE_DISABLED_MSG L"AspNetCore Module is disabled"
#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'."
#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."
#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."
#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."
#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"

View File

@ -189,11 +189,11 @@ IN_PROCESS_APPLICATION::ExecuteApplication()
hostFxrResolutionResult->GetArguments(context->m_argc, context->m_argv);
THROW_IF_FAILED(SetEnvironmentVariablesOnWorkerProcess());
context->m_hostFxr = HostFxr::CreateFromLoadedModule();
context->m_hostFxr.Load();
}
else
{
context->m_hostFxr = HostFxr(s_fMainCallback, nullptr, nullptr);
context->m_hostFxr.SetMain(s_fMainCallback);
}
// There can only ever be a single instance of .NET Core

View File

@ -257,7 +257,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
}
[ConditionalFact]
public async Task RemoveHostfxrFromApp_InProcessHostfxrInvalid()
public async Task RemoveHostfxrFromApp_InProcessHostfxrAPIAbsent()
{
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
deploymentParameters.ApplicationType = ApplicationType.Standalone;
@ -272,6 +272,20 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessHostfxrInvalid(deploymentResult), Logger);
}
[ConditionalFact]
public async Task RemoveHostfxrFromApp_InProcessHostfxrLoadFailure()
{
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
deploymentParameters.ApplicationType = ApplicationType.Standalone;
var deploymentResult = await DeployAsync(deploymentParameters);
// We don't distinguish between load failure types so making dll empty should be enough
File.WriteAllText(Path.Combine(deploymentResult.ContentRoot, "hostfxr.dll"), "");
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessHostfxrUnableToLoad(deploymentResult), Logger);
}
[ConditionalFact]
public async Task TargedDifferenceSharedFramework_FailedToFindNativeDependencies()
{

View File

@ -185,6 +185,11 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
return $"Hostfxr version used does not support 'hostfxr_get_native_search_directories', update the version of hostfxr to a higher version. Path to hostfxr: '(.*)'.";
}
public static string InProcessHostfxrUnableToLoad(IISDeploymentResult deploymentResult)
{
return $"Unable to load '(.*)'. This might be caused by a bitness mismatch between IIS application pool and published application.";
}
public static string InProcessFailedToFindNativeDependencies(IISDeploymentResult deploymentResult)
{
return "Invoking hostfxr to find the inprocess request handler failed without finding any native dependencies. " +