mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Testcase for bug 542263 - crash at NPObjWrapper_NewResolve or various other places
This commit is contained in:
parent
604f1ba55c
commit
deba97ab72
@ -468,10 +468,7 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
||||
return env
|
||||
|
||||
if IS_WIN32:
|
||||
ctypes = __import__('ctypes')
|
||||
wintypes = __import__('ctypes.wintypes')
|
||||
time = __import__('time')
|
||||
msvcrt = __import__('msvcrt')
|
||||
import ctypes, ctypes.wintypes, time, msvcrt
|
||||
PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe
|
||||
GetLastError = ctypes.windll.kernel32.GetLastError
|
||||
|
||||
|
@ -72,6 +72,7 @@ _MOCHITEST_FILES = \
|
||||
test_cookies.html \
|
||||
test_npn_timers.html \
|
||||
test_npn_asynccall.html \
|
||||
test_GCrace.html \
|
||||
$(NULL)
|
||||
|
||||
# test_npruntime_npnsetexception.html \ Disabled for e10s
|
||||
|
59
modules/plugin/test/mochitest/test_GCrace.html
Normal file
59
modules/plugin/test/mochitest/test_GCrace.html
Normal file
@ -0,0 +1,59 @@
|
||||
<head>
|
||||
<title>GC race with actors on the parent</title>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript"
|
||||
src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="/tests/SimpleTest/test.css" />
|
||||
<body onload="setTimeout(checkGCRace, 1000)">
|
||||
<p id="display"></p>
|
||||
|
||||
<embed id="p" type="application/x-test" wmode="window"></embed>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var nested = false;
|
||||
|
||||
function cb(f) {
|
||||
ok(!nested, "Callback shouldn't occur in a nested stack frame");
|
||||
try {
|
||||
f(35);
|
||||
ok(true, "Callback was called, no crash");
|
||||
}
|
||||
catch (e) {
|
||||
ok(false, "Exception calling callback object: " + e);
|
||||
}
|
||||
SimpleTest.executeSoon(removePlugin);
|
||||
}
|
||||
|
||||
function removePlugin() {
|
||||
var p = document.getElementById('p');
|
||||
p.parentNode.removeChild(p);
|
||||
p = null;
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
Components.utils.forceGC();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function checkGCRace() {
|
||||
nested = true;
|
||||
|
||||
// The plugin will hand back a function and immediately sleep.
|
||||
// We will lose our only reference to the function and force GC, followed
|
||||
// by calling us with that function object again. We should be able to
|
||||
// call the function and not crash.
|
||||
var p = document.getElementById('p');
|
||||
var f = p.checkGCRace(cb);
|
||||
f = null; // 'f' should be collected next GC
|
||||
|
||||
nested = false;
|
||||
|
||||
setTimeout(function() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
Components.utils.forceGC();
|
||||
}, 2000);
|
||||
}
|
||||
</script>
|
@ -94,6 +94,10 @@ with a boolean value, indicating whether the tests were successful.
|
||||
NPN_PluginThreadAsyncCall. When finished, calls the script callback
|
||||
with a boolean value, indicating whether the tests were successful.
|
||||
|
||||
* checkGCRace(callback) - return a function NPObject which may be called
|
||||
with the number '35'. Immediately after returning, sleep for 5 seconds, then
|
||||
call "callback" with the same NPObject.
|
||||
|
||||
== Private browsing ==
|
||||
|
||||
The test plugin object supports the following scriptable methods:
|
||||
|
@ -46,6 +46,7 @@
|
||||
#ifdef XP_WIN
|
||||
#include <process.h>
|
||||
#include <float.h>
|
||||
#include <windows.h>
|
||||
#define getpid _getpid
|
||||
#else
|
||||
#include <unistd.h>
|
||||
@ -144,6 +145,7 @@ static bool setCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
||||
static bool getCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
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 const NPUTF8* sPluginMethodIdentifierNames[] = {
|
||||
"npnEvaluateTest",
|
||||
@ -181,6 +183,7 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = {
|
||||
"getCookie",
|
||||
"getAuthInfo",
|
||||
"asyncCallbackTest",
|
||||
"checkGCRace",
|
||||
};
|
||||
static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
|
||||
static const ScriptableFunction sPluginMethodFunctions[ARRAY_LENGTH(sPluginMethodIdentifierNames)] = {
|
||||
@ -219,6 +222,7 @@ static const ScriptableFunction sPluginMethodFunctions[ARRAY_LENGTH(sPluginMetho
|
||||
getCookie,
|
||||
getAuthInfo,
|
||||
asyncCallbackTest,
|
||||
checkGCRace,
|
||||
};
|
||||
|
||||
struct URLNotifyData
|
||||
@ -2450,3 +2454,95 @@ asyncCallbackTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPV
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
GCRaceInvokeDefault(NPObject* o, const NPVariant* args, uint32_t argCount,
|
||||
NPVariant* result)
|
||||
{
|
||||
if (1 != argCount || !NPVARIANT_IS_INT32(args[0]) ||
|
||||
35 != NPVARIANT_TO_INT32(args[0]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const NPClass kGCRaceClass = {
|
||||
NP_CLASS_STRUCT_VERSION,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
GCRaceInvokeDefault,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
struct GCRaceData
|
||||
{
|
||||
GCRaceData(NPP npp, NPObject* callback, NPObject* localFunc)
|
||||
: npp_(npp)
|
||||
, callback_(callback)
|
||||
, localFunc_(localFunc)
|
||||
{
|
||||
NPN_RetainObject(callback_);
|
||||
NPN_RetainObject(localFunc_);
|
||||
}
|
||||
|
||||
~GCRaceData()
|
||||
{
|
||||
NPN_ReleaseObject(callback_);
|
||||
NPN_ReleaseObject(localFunc_);
|
||||
}
|
||||
|
||||
NPP npp_;
|
||||
NPObject* callback_;
|
||||
NPObject* localFunc_;
|
||||
};
|
||||
|
||||
static void
|
||||
FinishGCRace(void* closure)
|
||||
{
|
||||
GCRaceData* rd = static_cast<GCRaceData*>(closure);
|
||||
|
||||
#ifdef XP_WIN
|
||||
Sleep(5000);
|
||||
#else
|
||||
sleep(5);
|
||||
#endif
|
||||
|
||||
NPVariant arg;
|
||||
OBJECT_TO_NPVARIANT(rd->localFunc_, arg);
|
||||
|
||||
NPVariant result;
|
||||
bool ok = NPN_InvokeDefault(rd->npp_, rd->callback_, &arg, 1, &result);
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
NPN_ReleaseVariantValue(&result);
|
||||
delete rd;
|
||||
}
|
||||
|
||||
bool
|
||||
checkGCRace(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
||||
NPVariant* result)
|
||||
{
|
||||
if (1 != argCount || !NPVARIANT_IS_OBJECT(args[0]))
|
||||
return false;
|
||||
|
||||
NPP npp = static_cast<TestNPObject*>(npobj)->npp;
|
||||
|
||||
NPObject* localFunc =
|
||||
NPN_CreateObject(npp, const_cast<NPClass*>(&kGCRaceClass));
|
||||
|
||||
GCRaceData* rd =
|
||||
new GCRaceData(npp, NPVARIANT_TO_OBJECT(args[0]), localFunc);
|
||||
NPN_PluginThreadAsyncCall(npp, FinishGCRace, rd);
|
||||
|
||||
OBJECT_TO_NPVARIANT(localFunc, *result);
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user