зеркало из https://github.com/mozilla/gecko-dev.git
Testcase for bug 542263 - crash at NPObjWrapper_NewResolve or various other places
--HG-- extra : rebase_source : 92a3bc42926934ec4f077657d4c519809fa71df0
This commit is contained in:
Родитель
2bbb1c5271
Коммит
ba72a63e70
|
@ -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>
|
|
@ -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,101 @@ asyncCallbackTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPV
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
GCRaceInvoke(NPObject*, NPIdentifier, const NPVariant*, uint32_t, NPVariant*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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,
|
||||
GCRaceInvoke,
|
||||
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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче