зеркало из https://github.com/mozilla/gecko-dev.git
Bug 775378 - Trap exception handling calls to __abi_FailFast made by winrt delegate wrapper code. r=ted
This commit is contained in:
Родитель
b1a8d6ab25
Коммит
0e1f71c136
|
@ -6,6 +6,7 @@
|
|||
#include <windows.h>
|
||||
#include <delayimp.h>
|
||||
#include "nsToolkit.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
// If DllMain gets name mangled, it won't be seen.
|
||||
|
@ -51,6 +52,16 @@ BOOL APIENTRY DllMain(
|
|||
* Win7. To get around this we generate a dummy vccore lib with the three entry
|
||||
* points the initializer needs and load it in place of the real vccorlib. We
|
||||
* also have to add vccorlib and the system dlls to the delay load list.
|
||||
*
|
||||
* In addition to setting up dummyvccorlib, we also have additional checks for
|
||||
* for unexpected behavior, specifically:
|
||||
* - trap attempts to load entry points in dummyvccorlib. This is not expected
|
||||
* to happen in release code. It can happen during development if winrt apis
|
||||
* are accessed when running on the desktop, or when winrt objects are
|
||||
* accidentially placed in the global scope.
|
||||
* - trap and handle calls to vccorlib's __abi_FailFast in a breakpad compatible
|
||||
* way. __abi_FailFast is called by exception handling code generated by the
|
||||
* compiler for delegate events.
|
||||
*/
|
||||
static bool IsWin8OrHigher()
|
||||
{
|
||||
|
@ -71,29 +82,47 @@ static bool IsWin8OrHigher()
|
|||
|
||||
const char* kvccorlib = "vccorlib";
|
||||
const char* kwinrtprelim = "api-ms-win-core-winrt";
|
||||
const char* kfailfast = "?__abi_FailFast";
|
||||
|
||||
static bool IsWinRTDLLPresent(PDelayLoadInfo pdli, const char* aLibToken)
|
||||
static bool IsWinRTDLLNotPresent(PDelayLoadInfo pdli, const char* aLibToken)
|
||||
{
|
||||
return (!IsWin8OrHigher() && pdli->szDll &&
|
||||
!strnicmp(pdli->szDll, aLibToken, strlen(aLibToken)));
|
||||
}
|
||||
|
||||
static bool IsWinRTDLLPresent(PDelayLoadInfo pdli, const char* aLibToken)
|
||||
{
|
||||
return (IsWin8OrHigher() && pdli->szDll &&
|
||||
!strnicmp(pdli->szDll, aLibToken, strlen(aLibToken)));
|
||||
}
|
||||
|
||||
void __stdcall __abi_MozFailFast()
|
||||
{
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
FARPROC WINAPI DelayDllLoadHook(unsigned dliNotify, PDelayLoadInfo pdli)
|
||||
{
|
||||
if (dliNotify == dliNotePreLoadLibrary) {
|
||||
if (IsWinRTDLLPresent(pdli, kvccorlib)) {
|
||||
if (IsWinRTDLLNotPresent(pdli, kvccorlib)) {
|
||||
return (FARPROC)LoadLibraryA("dummyvccorlib.dll");
|
||||
}
|
||||
NS_ASSERTION(!IsWinRTDLLPresent(pdli, kwinrtprelim),
|
||||
NS_ASSERTION(!IsWinRTDLLNotPresent(pdli, kwinrtprelim),
|
||||
"Attempting to load winrt libs in non-metro environment. "
|
||||
"(Winrt variable type placed in global scope?)");
|
||||
}
|
||||
if (dliNotify == dliFailGetProc && IsWinRTDLLPresent(pdli, kvccorlib)) {
|
||||
if (dliNotify == dliFailGetProc && IsWinRTDLLNotPresent(pdli, kvccorlib)) {
|
||||
NS_WARNING("Attempting to access winrt vccorlib entry point in non-metro environment.");
|
||||
NS_WARNING(pdli->szDll);
|
||||
NS_WARNING(pdli->dlp.szProcName);
|
||||
NS_ABORT();
|
||||
}
|
||||
if (dliNotify == dliNotePreGetProcAddress &&
|
||||
IsWinRTDLLPresent(pdli, kvccorlib) &&
|
||||
pdli->dlp.szProcName &&
|
||||
!strnicmp(pdli->dlp.szProcName, kfailfast, strlen(kfailfast))) {
|
||||
return (FARPROC)__abi_MozFailFast;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче