Ignore:
Timestamp:
Feb 1, 2022, 9:33:58 AM (3 years ago)
Author:
[email protected]
Message:

Enhance sanitizeStackForVM() to assist with crash analysis.
https://bugs.webkit.org/show_bug.cgi?id=235752
rdar://81014601

Reviewed by Michael Saboff.

Source/JavaScriptCore:

  1. Remove the AssemblyHelpers version of sanitizeStack. Instead, make the 3 JIT operation functions call sanitizeStackForVM() instead. This ensures that sanitizeStack crashes are not obscured as generic JIT crashes.
  1. Add sanity check RELEASE_ASSERTs to VM::setLastStackTop() with a capture of the relevant variables for crash analysis.
  1. Fix logSanitizeStack() so that it no longer relies on vm.topCallFrame. vm.topCallFrame may not be properly initialized at all the places that sanitizeStackForVM() is called.
  1. Add a JSLock check to sanitizeStackForVM(), and return early if not owned by the current thread. If the JSLock is not owned by the current thread, we can't rely on vm.lastStackTop() being a sane value. Hence, it's not possible to do stack sanitization correctly.

Add sanity check RELEASE_ASSERTs to sanitizeStackForVM() with a capture of
the relevant variables for crash analysis.

  • jit/AssemblyHelpers.cpp:

(JSC::AssemblyHelpers::sanitizeStackInline): Deleted.

  • jit/AssemblyHelpers.h:
  • jit/JITOperations.cpp:

(JSC::JSC_DEFINE_JIT_OPERATION):

  • jit/ThunkGenerators.cpp:

(JSC::slowPathFor):

  • runtime/JSLock.cpp:

(JSC::JSLock::didAcquireLock):
(JSC::JSLock::grabAllLocks):

  • runtime/VM.cpp:

(JSC::VM::VM):
(JSC::VM::setLastStackTop):
(JSC::logSanitizeStack):
(JSC::sanitizeStackForVM):

  • runtime/VM.h:

Source/WTF:

  • wtf/Threading.h:

(WTF::Thread::savedStackPointerAtVMEntry const):
(WTF::Thread::savedLastStackTop const):
(WTF::Thread::savedStackPointerAtVMEntry): Deleted.
(WTF::Thread::savedLastStackTop): Deleted.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r288537 r288885  
    11/*
    2  * Copyright (C) 2008-2021 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008-2022 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    243243
    244244    interpreter = new Interpreter(*this);
    245     StackBounds stack = Thread::current().stack();
    246245    updateSoftReservedZoneSize(Options::softReservedZoneSize());
    247     setLastStackTop(stack.origin());
     246    setLastStackTop(Thread::current());
    248247
    249248    JSRunLoopTimer::Manager::shared().registerVM(*this);
     
    504503}
    505504
    506 void VM::setLastStackTop(void* lastStackTop)
    507 {
    508     m_lastStackTop = lastStackTop;
     505void VM::setLastStackTop(const Thread& thread)
     506{
     507    m_lastStackTop = thread.savedLastStackTop();
     508    auto& stack = thread.stack();
     509    RELEASE_ASSERT(stack.contains(m_lastStackTop), 0x5510, m_lastStackTop, stack.origin(), stack.end());
    509510}
    510511
     
    10511052}
    10521053
    1053 void logSanitizeStack(VM& vm)
    1054 {
    1055     if (Options::verboseSanitizeStack() && vm.topCallFrame) {
    1056         int dummy;
     1054static void logSanitizeStack(VM& vm)
     1055{
     1056    if (UNLIKELY(Options::verboseSanitizeStack())) {
    10571057        auto& stackBounds = Thread::current().stack();
    1058         dataLog(
    1059             "Sanitizing stack for VM = ", RawPointer(&vm), " with top call frame at ", RawPointer(vm.topCallFrame),
    1060             ", current stack pointer at ", RawPointer(&dummy), ", in ",
    1061             pointerDump(vm.topCallFrame->codeBlock()), ", last code origin = ",
    1062             vm.topCallFrame->codeOrigin(), ", last stack top = ", RawPointer(vm.lastStackTop()), ", in stack range [", RawPointer(stackBounds.origin()), ", ", RawPointer(stackBounds.end()), "]\n");
     1058        dataLogLn("Sanitizing stack for VM = ", RawPointer(&vm), ", current stack pointer at ", RawPointer(currentStackPointer()), ", last stack top = ", RawPointer(vm.lastStackTop()), ", in stack range (", RawPointer(stackBounds.end()), ", ", RawPointer(stackBounds.origin()), "]");
    10631059    }
    10641060}
     
    12711267void sanitizeStackForVM(VM& vm)
    12721268{
     1269    auto& thread = Thread::current();
     1270    auto& stack = thread.stack();
     1271    if (!vm.currentThreadIsHoldingAPILock())
     1272        return; // vm.lastStackTop() may not be set up correctly if JSLock is not held.
     1273
    12731274    logSanitizeStack(vm);
    1274     if (vm.topCallFrame) {
    1275         auto& stackBounds = Thread::current().stack();
    1276         ASSERT(vm.currentThreadIsHoldingAPILock());
    1277         ASSERT_UNUSED(stackBounds, stackBounds.contains(vm.lastStackTop()));
    1278     }
     1275
     1276    RELEASE_ASSERT(stack.contains(vm.lastStackTop()), 0xaa10, vm.lastStackTop(), stack.origin(), stack.end());
    12791277#if ENABLE(C_LOOP)
    12801278    vm.interpreter->cloopStack().sanitizeStack();
     
    12821280    sanitizeStackForVMImpl(&vm);
    12831281#endif
     1282    RELEASE_ASSERT(stack.contains(vm.lastStackTop()), 0xaa20, vm.lastStackTop(), stack.origin(), stack.end());
    12841283}
    12851284
Note: See TracChangeset for help on using the changeset viewer.