Skip to content

Commit 1db67fb

Browse files
committed
[1.10>master] [MERGE #5525 @leirocks] Use seperate error for xdata registration failures
Merge pull request #5525 from leirocks:xdata
2 parents c07fef6 + 11c5783 commit 1db67fb

File tree

9 files changed

+63
-23
lines changed

9 files changed

+63
-23
lines changed

lib/Backend/PDataManager.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
void PDataManager::RegisterPdata(RUNTIME_FUNCTION* pdataStart, _In_ const ULONG_PTR functionStart, _In_ const ULONG_PTR functionEnd, _Out_ PVOID* pdataTable, ULONG entryCount, ULONG maxEntryCount)
1616
{
1717
BOOLEAN success = FALSE;
18+
HRESULT hr = S_OK;
1819
if (AutoSystemInfo::Data.IsWin8OrLater())
1920
{
2021
Assert(pdataTable != NULL);
@@ -28,17 +29,22 @@ void PDataManager::RegisterPdata(RUNTIME_FUNCTION* pdataStart, _In_ const ULONG_
2829
/*RangeBase*/ functionStart,
2930
/*RangeEnd*/ functionEnd);
3031
success = NT_SUCCESS(status);
31-
if (success)
32-
{
33-
Assert(pdataTable);
34-
}
32+
Assert(!success || pdataTable);
33+
hr = status;
3534
}
3635
else
3736
{
3837
*pdataTable = pdataStart;
3938
success = RtlAddFunctionTable(pdataStart, entryCount, functionStart);
39+
if (!success)
40+
{
41+
hr = E_OUTOFMEMORY; // only OOM error can happen for RtlAddFunctionTable
42+
}
43+
}
44+
if (!success)
45+
{
46+
Js::Throw::XDataRegistrationError(hr, functionStart);
4047
}
41-
Js::Throw::CheckAndThrowOutOfMemory(success);
4248
}
4349

4450
void PDataManager::UnregisterPdata(RUNTIME_FUNCTION* pdata)

lib/Common/Core/DelayLoadLibrary.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ NtdllLibrary::NTSTATUS NtdllLibrary::AddGrowableFunctionTable( _Out_ PVOID * Dyn
112112
}
113113
}
114114

115+
#if DBG
116+
// Validate the PDATA was not registered or already unregistered
117+
ULONG_PTR imageBase = 0;
118+
RUNTIME_FUNCTION *runtimeFunction = RtlLookupFunctionEntry((DWORD64)RangeBase, &imageBase, nullptr);
119+
Assert(runtimeFunction == NULL);
120+
#endif
121+
115122
*DynamicTable = nullptr;
116123
NTSTATUS status = addGrowableFunctionTable(DynamicTable,
117124
FunctionTable,

lib/Common/Exceptions/ReportError.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ void ReportFatalException(
1010
__in ULONG_PTR context,
1111
__in HRESULT exceptionCode,
1212
__in ErrorReason reasonCode,
13-
__in ULONG scenario)
13+
__in ULONG_PTR scenario)
1414
{
1515
// avoid the error text methods to be optimized out.
1616
UNREFERENCED_PARAMETER(scenario);
@@ -181,6 +181,11 @@ _NOINLINE void OutOfMemoryAllocationPolicy_unrecoverable_error()
181181
ReportFatalException(NULL, E_OUTOFMEMORY, Fatal_OutOfMemory, scenario);
182182
}
183183

184+
_NOINLINE void XDataRegistration_unrecoverable_error(HRESULT hr, ULONG_PTR scenario)
185+
{
186+
ReportFatalException(NULL, hr, Fatal_XDataRegistration, scenario);
187+
}
188+
184189
///////
185190
//
186191
// The following variety of OOM unrecoverable errors are similar to the ones above

lib/Common/Exceptions/ReportError.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@ enum ErrorReason
3030
Fatal_OutOfMemory = 22,
3131
// Unused = 23,
3232
Fatal_JsBuiltIn_Error = 24,
33+
Fatal_XDataRegistration = 25,
3334
};
3435

3536
extern "C" void ReportFatalException(
3637
__in ULONG_PTR context,
3738
__in HRESULT exceptionCode,
3839
__in ErrorReason reasonCode,
39-
__in ULONG scenario);
40+
__in ULONG_PTR scenario);
4041

4142
// We can have other error handle code path with
4243
// unique call stack so we can collect data in Dr. Watson.
@@ -89,6 +90,8 @@ void OutOfMemoryTooManyPinnedObjects_unrecoverable_error_notvisible();
8990
void OutOfMemoryTooManyClosedContexts_unrecoverable_error_notvisible();
9091
void OutOfMemoryAllocationPolicy_unrecoverable_error_notvisible();
9192

93+
void XDataRegistration_unrecoverable_error(HRESULT hr, ULONG_PTR scenario);
94+
9295
inline void OutOfMemoryTooManyPinnedObjects_unrecoverable_error(BYTE visibility)
9396
{
9497
switch (visibility)

lib/Common/Exceptions/Throw.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,21 @@ namespace Js {
125125
}
126126
throw OutOfMemoryException();
127127
}
128-
void Throw::CheckAndThrowOutOfMemory(BOOLEAN status)
128+
129+
#if !defined(_M_IX86) && defined(_WIN32)
130+
void Throw::XDataRegistrationError(HRESULT hr, ULONG_PTR funcStart)
129131
{
130-
if (!status)
132+
ULONG_PTR imageBase = 0;
133+
RUNTIME_FUNCTION *runtimeFunction = RtlLookupFunctionEntry(funcStart, &imageBase, nullptr);
134+
135+
if (JsUtil::ExternalApi::GetCurrentThreadContextId())
131136
{
132-
OutOfMemory();
137+
XDataRegistration_unrecoverable_error(hr, (ULONG_PTR)runtimeFunction);
133138
}
139+
throw OutOfMemoryException();
134140
}
141+
#endif
142+
135143
void Throw::StackOverflow(ScriptContext *scriptContext, PVOID returnAddress)
136144
{
137145
#ifdef ENABLE_DEBUG_CONFIG_OPTIONS

lib/Common/Exceptions/Throw.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ namespace Js {
3030
#ifdef ENABLE_JS_BUILTINS
3131
static void __declspec(noreturn) FatalJsBuiltInError();
3232
#endif
33-
static void CheckAndThrowOutOfMemory(BOOLEAN status);
33+
34+
#if !defined(_M_IX86) && defined(_WIN32)
35+
static void XDataRegistrationError(HRESULT hr, ULONG_PTR funcStart);
36+
#endif
3437

3538
static bool ReportAssert(__in LPCSTR fileName, uint lineNumber, __in LPCSTR error, __in LPCSTR message);
3639
static void LogAssert();

lib/Common/Memory/amd64/XDataAllocator.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -124,29 +124,33 @@ void XDataAllocator::Register(XDataAllocation * xdataInfo, ULONG_PTR functionSta
124124
xdataInfo->pdata.EndAddress = (DWORD)(xdataInfo->pdata.BeginAddress + functionSize);
125125
xdataInfo->pdata.UnwindInfoAddress = (DWORD)((intptr_t)xdataInfo->address - baseAddress);
126126

127+
HRESULT hr = S_OK;
127128
BOOLEAN success = FALSE;
128129
if (AutoSystemInfo::Data.IsWin8OrLater())
129130
{
130-
#if DBG
131-
// Validate the PDATA was not registered or unregistered
132-
ULONG64 imageBase = 0;
133-
RUNTIME_FUNCTION *runtimeFunction = RtlLookupFunctionEntry((DWORD64)functionStart, &imageBase, nullptr);
134-
Assert(runtimeFunction == NULL);
135-
#endif
136-
137131
NTSTATUS status = NtdllLibrary::Instance->AddGrowableFunctionTable(&xdataInfo->functionTable,
138132
&xdataInfo->pdata,
139133
/*MaxEntryCount*/ 1,
140134
/*Valid entry count*/ 1,
141135
/*RangeBase*/ functionStart,
142136
/*RangeEnd*/ functionStart + functionSize);
143137
success = NT_SUCCESS(status);
138+
hr = status;
139+
144140
}
145141
else
146142
{
147143
success = RtlAddFunctionTable(&xdataInfo->pdata, 1, functionStart);
144+
if (!success)
145+
{
146+
hr = E_OUTOFMEMORY; // only OOM error can happen for RtlAddFunctionTable
147+
}
148+
}
149+
150+
if (!success)
151+
{
152+
Js::Throw::XDataRegistrationError(hr, functionStart);
148153
}
149-
Js::Throw::CheckAndThrowOutOfMemory(success);
150154

151155
#if DBG
152156
// Validate that the PDATA registration succeeded

lib/Common/Memory/arm/XDataAllocator.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ void XDataAllocator::Register(XDataAllocation * xdataInfo, DWORD functionStart,
8888
/*RangeBase*/ functionStart,
8989
/*RangeEnd*/ functionStart + functionSize);
9090

91-
Js::Throw::CheckAndThrowOutOfMemory(NT_SUCCESS(status));
91+
if (!NT_SUCCESS(status))
92+
{
93+
Js::Throw::XDataRegistrationError(status, functionStart);
94+
}
9295

9396
#else // !_WIN32
9497
Assert(ReadHead(xdataInfo->address)); // should be non-empty .eh_frame

lib/Common/Memory/arm64/XDataAllocator.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,12 @@ void XDataAllocator::Register(XDataAllocation * xdataInfo, ULONG_PTR functionSta
132132
/*RangeBase*/ functionStart,
133133
/*RangeEnd*/ functionStart + functionSize);
134134
BOOLEAN success = NT_SUCCESS(status);
135-
if (success)
135+
Assert(!success || xdataInfo->functionTable != nullptr);
136+
137+
if (!success)
136138
{
137-
Assert(xdataInfo->functionTable != nullptr);
139+
Js::Throw::XDataRegistrationError(status, functionStart);
138140
}
139-
Js::Throw::CheckAndThrowOutOfMemory(success);
140141

141142
#if DBG
142143
// Validate that the PDATA registration succeeded

0 commit comments

Comments
 (0)