Title: [258386] trunk/Source
Revision
258386
Author
ysuz...@apple.com
Date
2020-03-13 00:53:28 -0700 (Fri, 13 Mar 2020)

Log Message

Report crashed cell in jsCast in debug builds
https://bugs.webkit.org/show_bug.cgi?id=209041
<rdar://problem/59705631>

Reviewed by Mark Lam.

Source/_javascript_Core:

To collect more information when crashing with jsCast, we attempt to use reportZappedCellAndCrash.
If it succeeds, we can get more information in registers. We enable this only for ASSERT_ENABLED
build. For non ASSERT_ENABLED, we keep the original assertion since this assertion can be enabled
via ENABLE(SECURITY_ASSERTIONS).

* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::appendToMarkStack):
(JSC::SlotVisitor::visitChildren):
(JSC::SlotVisitor::reportZappedCellAndCrash): Deleted.
* heap/SlotVisitor.h:
* runtime/JSCast.h:
(JSC::jsCast):
* runtime/JSCell.cpp:
(JSC::reportZappedCellAndCrash):
* runtime/JSCell.h:

Source/WebCore:

We should take JSLock when touching JSC::VM.

* page/MemoryRelease.cpp:
(WebCore::logMemoryStatisticsAtTimeOfDeath):
* page/PerformanceLogging.cpp:
(WebCore::PerformanceLogging::memoryUsageStatistics):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (258385 => 258386)


--- trunk/Source/_javascript_Core/ChangeLog	2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-03-13 07:53:28 UTC (rev 258386)
@@ -1,3 +1,27 @@
+2020-03-12  Yusuke Suzuki  <ysuz...@apple.com>
+
+        Report crashed cell in jsCast in debug builds
+        https://bugs.webkit.org/show_bug.cgi?id=209041
+        <rdar://problem/59705631>
+
+        Reviewed by Mark Lam.
+
+        To collect more information when crashing with jsCast, we attempt to use reportZappedCellAndCrash.
+        If it succeeds, we can get more information in registers. We enable this only for ASSERT_ENABLED
+        build. For non ASSERT_ENABLED, we keep the original assertion since this assertion can be enabled
+        via ENABLE(SECURITY_ASSERTIONS).
+
+        * heap/SlotVisitor.cpp:
+        (JSC::SlotVisitor::appendToMarkStack):
+        (JSC::SlotVisitor::visitChildren):
+        (JSC::SlotVisitor::reportZappedCellAndCrash): Deleted.
+        * heap/SlotVisitor.h:
+        * runtime/JSCast.h:
+        (JSC::jsCast):
+        * runtime/JSCell.cpp:
+        (JSC::reportZappedCellAndCrash):
+        * runtime/JSCell.h:
+
 2020-03-12  Keith Miller  <keith_mil...@apple.com>
 
         DFG nodes that take a TypedArray's storage need to keepAlive the TypedArray

Modified: trunk/Source/_javascript_Core/heap/SlotVisitor.cpp (258385 => 258386)


--- trunk/Source/_javascript_Core/heap/SlotVisitor.cpp	2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/_javascript_Core/heap/SlotVisitor.cpp	2020-03-13 07:53:28 UTC (rev 258386)
@@ -294,7 +294,7 @@
 #if CPU(X86_64)
     if (UNLIKELY(Options::dumpZappedCellCrashData())) {
         if (UNLIKELY(cell->isZapped()))
-            reportZappedCellAndCrash(cell);
+            reportZappedCellAndCrash(m_heap, cell);
     }
 #endif
     ASSERT(!cell->isZapped());
@@ -404,7 +404,7 @@
                 methodTable->visitChildren(const_cast<JSCell*>(cell), *this);
                 break;
             }
-            reportZappedCellAndCrash(const_cast<JSCell*>(cell));
+            reportZappedCellAndCrash(m_heap, const_cast<JSCell*>(cell));
         }
 #endif
         cell->methodTable(vm())->visitChildren(const_cast<JSCell*>(cell), *this);
@@ -825,46 +825,4 @@
     m_currentSolver->addParallelTask(task, *m_currentConstraint);
 }
 
-#if CPU(X86_64)
-NEVER_INLINE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void SlotVisitor::reportZappedCellAndCrash(JSCell* cell)
-{
-    MarkedBlock::Handle* foundBlockHandle = nullptr;
-    uint64_t* cellWords = reinterpret_cast_ptr<uint64_t*>(cell);
-
-    uintptr_t cellAddress = bitwise_cast<uintptr_t>(cell);
-    uint64_t headerWord = cellWords[0];
-    uint64_t zapReasonAndMore = cellWords[1];
-    unsigned subspaceHash = 0;
-    size_t cellSize = 0;
-
-    m_heap.objectSpace().forEachBlock([&] (MarkedBlock::Handle* blockHandle) {
-        if (blockHandle->contains(cell)) {
-            foundBlockHandle = blockHandle;
-            return IterationStatus::Done;
-        }
-        return IterationStatus::Continue;
-    });
-
-    uint64_t variousState = 0;
-    MarkedBlock* foundBlock = nullptr;
-    if (foundBlockHandle) {
-        foundBlock = &foundBlockHandle->block();
-        subspaceHash = StringHasher::computeHash(foundBlockHandle->subspace()->name());
-        cellSize = foundBlockHandle->cellSize();
-
-        variousState |= static_cast<uint64_t>(foundBlockHandle->isFreeListed()) << 0;
-        variousState |= static_cast<uint64_t>(foundBlockHandle->isAllocated()) << 1;
-        variousState |= static_cast<uint64_t>(foundBlockHandle->isEmpty()) << 2;
-        variousState |= static_cast<uint64_t>(foundBlockHandle->needsDestruction()) << 3;
-        variousState |= static_cast<uint64_t>(foundBlock->isNewlyAllocated(cell)) << 4;
-
-        ptrdiff_t cellOffset = cellAddress - reinterpret_cast<uint64_t>(foundBlockHandle->start());
-        bool cellIsProperlyAligned = !(cellOffset % cellSize);
-        variousState |= static_cast<uint64_t>(cellIsProperlyAligned) << 5;
-    }
-
-    CRASH_WITH_INFO(cellAddress, headerWord, zapReasonAndMore, subspaceHash, cellSize, foundBlock, variousState);
-}
-#endif // PLATFORM(MAC)
-
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/heap/SlotVisitor.h (258385 => 258386)


--- trunk/Source/_javascript_Core/heap/SlotVisitor.h	2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/_javascript_Core/heap/SlotVisitor.h	2020-03-13 07:53:28 UTC (rev 258386)
@@ -227,10 +227,6 @@
     bool hasWork(const AbstractLocker&);
     bool didReachTermination(const AbstractLocker&);
 
-#if CPU(X86_64)
-    NEVER_INLINE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void reportZappedCellAndCrash(JSCell*);
-#endif
-
     template<typename Func>
     IterationStatus forEachMarkStack(const Func&);
 

Modified: trunk/Source/_javascript_Core/runtime/JSCast.h (258385 => 258386)


--- trunk/Source/_javascript_Core/runtime/JSCast.h	2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/_javascript_Core/runtime/JSCast.h	2020-03-13 07:53:28 UTC (rev 258386)
@@ -33,7 +33,12 @@
 inline To jsCast(From* from)
 {
     static_assert(std::is_base_of<JSCell, typename std::remove_pointer<To>::type>::value && std::is_base_of<JSCell, typename std::remove_pointer<From>::type>::value, "JS casting expects that the types you are casting to/from are subclasses of JSCell");
+#if (ASSERT_ENABLED || ENABLE(SECURITY_ASSERTIONS)) && CPU(X86_64)
+    if (from && !from->JSCell::inherits(from->JSCell::vm(), std::remove_pointer<To>::type::info()))
+        reportZappedCellAndCrash(*from->JSCell::heap(), from);
+#else
     ASSERT_WITH_SECURITY_IMPLICATION(!from || from->JSCell::inherits(from->JSCell::vm(), std::remove_pointer<To>::type::info()));
+#endif
     return static_cast<To>(from);
 }
 
@@ -41,7 +46,14 @@
 inline To jsCast(JSValue from)
 {
     static_assert(std::is_base_of<JSCell, typename std::remove_pointer<To>::type>::value, "JS casting expects that the types you are casting to is a subclass of JSCell");
+#if (ASSERT_ENABLED || ENABLE(SECURITY_ASSERTIONS)) && CPU(X86_64)
+    ASSERT(from.isCell());
+    JSCell* cell = from.asCell();
+    if (!cell->JSCell::inherits(cell->vm(), std::remove_pointer<To>::type::info()))
+        reportZappedCellAndCrash(*cell->JSCell::heap(), cell);
+#else
     ASSERT_WITH_SECURITY_IMPLICATION(from.isCell() && from.asCell()->JSCell::inherits(from.asCell()->vm(), std::remove_pointer<To>::type::info()));
+#endif
     return static_cast<To>(from.asCell());
 }
 

Modified: trunk/Source/_javascript_Core/runtime/JSCell.cpp (258385 => 258386)


--- trunk/Source/_javascript_Core/runtime/JSCell.cpp	2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/_javascript_Core/runtime/JSCell.cpp	2020-03-13 07:53:28 UTC (rev 258386)
@@ -24,11 +24,13 @@
 #include "JSCell.h"
 
 #include "ArrayBufferView.h"
+#include "BlockDirectoryInlines.h"
 #include "JSCInlines.h"
 #include "JSCast.h"
 #include "JSFunction.h"
 #include "JSString.h"
 #include "JSObject.h"
+#include "MarkedBlockInlines.h"
 #include "NumberObject.h"
 #include <wtf/LockAlgorithmInlines.h>
 #include <wtf/MathExtras.h>
@@ -316,4 +318,46 @@
     IndexingTypeLockAlgorithm::unlockSlow(*lock);
 }
 
+#if CPU(X86_64)
+NEVER_INLINE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void reportZappedCellAndCrash(Heap& heap, const JSCell* cell)
+{
+    MarkedBlock::Handle* foundBlockHandle = nullptr;
+    uint64_t* cellWords = bitwise_cast<uint64_t*>(cell);
+
+    uintptr_t cellAddress = bitwise_cast<uintptr_t>(cell);
+    uint64_t headerWord = cellWords[0];
+    uint64_t zapReasonAndMore = cellWords[1];
+    unsigned subspaceHash = 0;
+    size_t cellSize = 0;
+
+    heap.objectSpace().forEachBlock([&] (MarkedBlock::Handle* blockHandle) {
+        if (blockHandle->contains(bitwise_cast<JSCell*>(cell))) {
+            foundBlockHandle = blockHandle;
+            return IterationStatus::Done;
+        }
+        return IterationStatus::Continue;
+    });
+
+    uint64_t variousState = 0;
+    MarkedBlock* foundBlock = nullptr;
+    if (foundBlockHandle) {
+        foundBlock = &foundBlockHandle->block();
+        subspaceHash = StringHasher::computeHash(foundBlockHandle->subspace()->name());
+        cellSize = foundBlockHandle->cellSize();
+
+        variousState |= static_cast<uint64_t>(foundBlockHandle->isFreeListed()) << 0;
+        variousState |= static_cast<uint64_t>(foundBlockHandle->isAllocated()) << 1;
+        variousState |= static_cast<uint64_t>(foundBlockHandle->isEmpty()) << 2;
+        variousState |= static_cast<uint64_t>(foundBlockHandle->needsDestruction()) << 3;
+        variousState |= static_cast<uint64_t>(foundBlock->isNewlyAllocated(cell)) << 4;
+
+        ptrdiff_t cellOffset = cellAddress - reinterpret_cast<uint64_t>(foundBlockHandle->start());
+        bool cellIsProperlyAligned = !(cellOffset % cellSize);
+        variousState |= static_cast<uint64_t>(cellIsProperlyAligned) << 5;
+    }
+
+    CRASH_WITH_INFO(cellAddress, headerWord, zapReasonAndMore, subspaceHash, cellSize, foundBlock, variousState);
+}
+#endif // CPU(X86_64)
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/JSCell.h (258385 => 258386)


--- trunk/Source/_javascript_Core/runtime/JSCell.h	2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/_javascript_Core/runtime/JSCell.h	2020-03-13 07:53:28 UTC (rev 258386)
@@ -307,4 +307,8 @@
     return Type::template subspaceFor<Type, SubspaceAccess::Concurrently>(vm);
 }
 
+#if CPU(X86_64)
+JS_EXPORT_PRIVATE NEVER_INLINE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void reportZappedCellAndCrash(Heap&, const JSCell*);
+#endif
+
 } // namespace JSC

Modified: trunk/Source/WebCore/ChangeLog (258385 => 258386)


--- trunk/Source/WebCore/ChangeLog	2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/WebCore/ChangeLog	2020-03-13 07:53:28 UTC (rev 258386)
@@ -1,3 +1,18 @@
+2020-03-12  Yusuke Suzuki  <ysuz...@apple.com>
+
+        Report crashed cell in jsCast in debug builds
+        https://bugs.webkit.org/show_bug.cgi?id=209041
+        <rdar://problem/59705631>
+
+        Reviewed by Mark Lam.
+
+        We should take JSLock when touching JSC::VM.
+
+        * page/MemoryRelease.cpp:
+        (WebCore::logMemoryStatisticsAtTimeOfDeath):
+        * page/PerformanceLogging.cpp:
+        (WebCore::PerformanceLogging::memoryUsageStatistics):
+
 2020-03-12  Cathie Chen  <cathiec...@igalia.com>
 
         REGRESSION(r255957): Element with scroll-behavior:smooth isn't draggable after r255957

Modified: trunk/Source/WebCore/page/MemoryRelease.cpp (258385 => 258386)


--- trunk/Source/WebCore/page/MemoryRelease.cpp	2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/WebCore/page/MemoryRelease.cpp	2020-03-13 07:53:28 UTC (rev 258386)
@@ -192,6 +192,7 @@
 #endif
 
     auto& vm = commonVM();
+    JSC::JSLockHolder locker(vm);
     RELEASE_LOG(MemoryPressure, "Memory usage statistics at time of death:");
     RELEASE_LOG(MemoryPressure, "GC heap size: %zu", vm.heap.size());
     RELEASE_LOG(MemoryPressure, "GC heap extra memory size: %zu", vm.heap.extraMemorySize());

Modified: trunk/Source/WebCore/page/PerformanceLogging.cpp (258385 => 258386)


--- trunk/Source/WebCore/page/PerformanceLogging.cpp	2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/WebCore/page/PerformanceLogging.cpp	2020-03-13 07:53:28 UTC (rev 258386)
@@ -56,6 +56,7 @@
     HashMap<const char*, size_t> stats;
 
     auto& vm = commonVM();
+    JSC::JSLockHolder locker(vm);
     stats.add("_javascript__gc_heap_capacity", vm.heap.capacity());
     stats.add("_javascript__gc_heap_extra_memory_size", vm.heap.extraMemorySize());
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to