diff --git a/modules/plugin/test/mochitest/Makefile.in b/modules/plugin/test/mochitest/Makefile.in index 4c11e61d5f1..b3caba2fa27 100644 --- a/modules/plugin/test/mochitest/Makefile.in +++ b/modules/plugin/test/mochitest/Makefile.in @@ -80,6 +80,7 @@ ifdef MOZ_IPC _MOCHITEST_FILES += \ test_crashing.html \ test_crashing2.html \ + test_hanging.html \ crashing_subpage.html \ $(NULL) endif diff --git a/modules/plugin/test/mochitest/test_hanging.html b/modules/plugin/test/mochitest/test_hanging.html new file mode 100644 index 00000000000..d9fcc45366d --- /dev/null +++ b/modules/plugin/test/mochitest/test_hanging.html @@ -0,0 +1,75 @@ + + Plugin hanging + + + + + + + diff --git a/modules/plugin/test/testplugin/nptest.cpp b/modules/plugin/test/testplugin/nptest.cpp index 0b203c7dac5..747f8f86bc9 100644 --- a/modules/plugin/test/testplugin/nptest.cpp +++ b/modules/plugin/test/testplugin/nptest.cpp @@ -67,8 +67,8 @@ int gCrashCount = 0; -void -IntentionalCrash() +static void +NoteIntentionalCrash() { char* bloatLog = getenv("XPCOM_MEM_BLOAT_LOG"); if (bloatLog) { @@ -85,6 +85,13 @@ IntentionalCrash() fprintf(processfd, "==> process %d will purposefully crash\n", getpid()); fclose(processfd); } +} + +static void +IntentionalCrash() +{ + NoteIntentionalCrash(); + int *pi = NULL; *pi = 55; // Crash dereferencing null pointer ++gCrashCount; @@ -146,6 +153,7 @@ static bool getCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, static bool getAuthInfo(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); static bool asyncCallbackTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); static bool checkGCRace(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); +static bool hangPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); static const NPUTF8* sPluginMethodIdentifierNames[] = { "npnEvaluateTest", @@ -184,6 +192,7 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = { "getAuthInfo", "asyncCallbackTest", "checkGCRace", + "hang", }; static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)]; static const ScriptableFunction sPluginMethodFunctions[ARRAY_LENGTH(sPluginMethodIdentifierNames)] = { @@ -223,6 +232,7 @@ static const ScriptableFunction sPluginMethodFunctions[ARRAY_LENGTH(sPluginMetho getAuthInfo, asyncCallbackTest, checkGCRace, + hangPlugin, }; struct URLNotifyData @@ -2552,3 +2562,21 @@ checkGCRace(NPObject* npobj, const NPVariant* args, uint32_t argCount, OBJECT_TO_NPVARIANT(localFunc, *result); return true; } + +bool +hangPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, + NPVariant* result) +{ + NoteIntentionalCrash(); + +#ifdef XP_WIN + Sleep(100000000); +#else + pause(); +#endif + // NB: returning true here means that we weren't terminated, and + // thus the hang detection/handling didn't work correctly. The + // test harness will succeed in calling this function, and the + // test will fail. + return true; +}