Bug 1055206 - Handle null frames in Debugger::onLogAllocationSite. r=jimb
authorNick Fitzgerald <fitzgen@gmail.com>
Tue, 19 Aug 2014 15:52:02 -0700
changeset 214796 35c265c62076dec4ebb88d5ca34525a958617bd8
parent 214795 6e84c39a1420d3d2b9569df9d41ab4df947e69b6
child 214797 c181933a82736758370afcea2a5a733b223688ab
push idunknown
push userunknown
push dateunknown
reviewersjimb
bugs1055206
milestone34.0a1
Bug 1055206 - Handle null frames in Debugger::onLogAllocationSite. r=jimb
js/src/jsapi-tests/moz.build
js/src/jsapi-tests/testSavedStacks.cpp
js/src/vm/Debugger.h
js/src/vm/DebuggerMemory.cpp
--- a/js/src/jsapi-tests/moz.build
+++ b/js/src/jsapi-tests/moz.build
@@ -58,16 +58,17 @@ UNIFIED_SOURCES += [
     'testParseJSON.cpp',
     'testPersistentRooted.cpp',
     'testProfileStrings.cpp',
     'testPropCache.cpp',
     'testRegExp.cpp',
     'testResolveRecursion.cpp',
     'tests.cpp',
     'testSameValue.cpp',
+    'testSavedStacks.cpp',
     'testScriptInfo.cpp',
     'testScriptObject.cpp',
     'testSetProperty.cpp',
     'testSetPropertyIgnoringNamedGetter.cpp',
     'testSourcePolicy.cpp',
     'testStringBuffer.cpp',
     'testStructuredClone.cpp',
     'testSymbol.cpp',
new file mode 100644
--- /dev/null
+++ b/js/src/jsapi-tests/testSavedStacks.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "jscompartment.h"
+#include "jsfriendapi.h"
+#include "jsstr.h"
+
+#include "jsapi-tests/tests.h"
+
+#include "vm/ArrayObject.h"
+#include "vm/SavedStacks.h"
+
+BEGIN_TEST(testSavedStacks_withNoStack)
+{
+    JSCompartment *compartment = js::GetContextCompartment(cx);
+    compartment->setObjectMetadataCallback(js::SavedStacksMetadataCallback);
+    JS::RootedObject obj(cx, js::NewDenseEmptyArray(cx));
+    compartment->setObjectMetadataCallback(nullptr);
+    return true;
+}
+END_TEST(testSavedStacks_withNoStack)
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -197,17 +197,17 @@ class Debugger : private mozilla::Linked
     GlobalObjectSet debuggees;          /* Debuggee globals. Cross-compartment weak references. */
     js::HeapPtrObject uncaughtExceptionHook; /* Strong reference. */
     bool enabled;
     JSCList breakpoints;                /* Circular list of all js::Breakpoints in this debugger */
 
     struct AllocationSite : public mozilla::LinkedListElement<AllocationSite>
     {
         AllocationSite(HandleObject frame) : frame(frame) {
-            JS_ASSERT(UncheckedUnwrap(frame)->is<SavedFrame>());
+            JS_ASSERT_IF(frame, UncheckedUnwrap(frame)->is<SavedFrame>());
         };
         RelocatablePtrObject frame;
     };
     typedef mozilla::LinkedList<AllocationSite> AllocationSiteList;
 
     bool trackingAllocationSites;
     AllocationSiteList allocationsLog;
     size_t allocationsLogLength;
@@ -785,17 +785,17 @@ Debugger::onNewGlobalObject(JSContext *c
 #endif
     if (!JS_CLIST_IS_EMPTY(&cx->runtime()->onNewGlobalObjectWatchers))
         Debugger::slowPathOnNewGlobalObject(cx, global);
 }
 
 bool
 Debugger::onLogAllocationSite(JSContext *cx, HandleSavedFrame frame)
 {
-    GlobalObject::DebuggerVector *dbgs = frame->global().getDebuggers();
+    GlobalObject::DebuggerVector *dbgs = cx->global()->getDebuggers();
     if (!dbgs || dbgs->empty())
         return true;
     return Debugger::slowPathOnLogAllocationSite(cx, frame, *dbgs);
 }
 
 extern bool
 EvaluateInEnv(JSContext *cx, Handle<Env*> env, HandleValue thisv, AbstractFramePtr frame,
               mozilla::Range<const jschar> chars, const char *filename, unsigned lineno,
--- a/js/src/vm/DebuggerMemory.cpp
+++ b/js/src/vm/DebuggerMemory.cpp
@@ -193,17 +193,17 @@ DebuggerMemory::drainAllocationsLog(JSCo
 
     RootedObject result(cx, NewDenseAllocatedArray(cx, length));
     if (!result)
         return false;
     result->ensureDenseInitializedLength(cx, 0, length);
 
     for (size_t i = 0; i < length; i++) {
         Debugger::AllocationSite *allocSite = dbg->allocationsLog.popFirst();
-        result->setDenseElement(i, ObjectValue(*allocSite->frame));
+        result->setDenseElement(i, ObjectOrNullValue(allocSite->frame));
         js_delete(allocSite);
     }
 
     dbg->allocationsLogLength = 0;
     args.rval().setObject(*result);
     return true;
 }