Bug 139000

Summary: r176455: ASSERT(!m_vector.isEmpty()) in IntendedStructureChain.cpp(143)
Product: WebKit Reporter: Michael Saboff <msaboff>
Component: JavaScriptCoreAssignee: Michael Saboff <msaboff>
Severity: Normal CC: ggaren, jimoase
Priority: P2 Keywords: InRadar
Version: 528+ (Nightly build)   
Hardware: All   
OS: All   
Bug Depends on:    
Bug Blocks: 139194    
Description Flags
Patch darin: review+

Description Michael Saboff 2014-11-21 22:46:51 PST
From <rdar://problem/19046388>

1. Get a spade build of Safari with open source release r176455 or later.
2. Open Safari and navigate to http://www.bobistheoilguy.com/castrol-edge-qa/
3. You may need to scroll.


Crash.  With a Debug build:

ASSERTION FAILED: !m_vector.isEmpty()
/Volumes/Data/src/webkit/Source/JavaScriptCore/runtime/IntendedStructureChain.cpp(143) : JSC::JSObject *JSC::IntendedStructureChain::terminalPrototype() const
1   0x10dea92b0 WTFCrash
2   0x10dadfe96 JSC::IntendedStructureChain::terminalPrototype() const
3   0x10de62c96 JSC::ComplexGetStatus::computeFor(JSC::CodeBlock*, JSC::Structure*, JSC::StructureChain*, unsigned int, WTF::StringImpl*)
4   0x10da286f9 JSC::GetByIdStatus::computeForStubInfo(JSC::ConcurrentJITLocker const&, JSC::CodeBlock*, JSC::StructureStubInfo*, WTF::StringImpl*, JSC::CallLinkStatus::ExitSiteData)
5   0x10da2799b JSC::GetByIdStatus::computeFor(JSC::CodeBlock*, WTF::HashMap<JSC::CodeOrigin, JSC::StructureStubInfo*, JSC::CodeOriginApproximateHash, WTF::HashTraits<JSC::CodeOrigin>, WTF::HashTraits<JSC::StructureStubInfo*> >&, unsigned int, WTF::StringImpl*)
6   0x10da29fbb JSC::GetByIdStatus::computeFor(JSC::CodeBlock*, JSC::CodeBlock*, WTF::HashMap<JSC::CodeOrigin, JSC::StructureStubInfo*, JSC::CodeOriginApproximateHash, WTF::HashTraits<JSC::CodeOrigin>, WTF::HashTraits<JSC::StructureStubInfo*> >&, WTF::HashMap<JSC::CodeOrigin, JSC::StructureStubInfo*, JSC::CodeOriginApproximateHash, WTF::HashTraits<JSC::CodeOrigin>, WTF::HashTraits<JSC::StructureStubInfo*> >&, JSC::CodeOrigin, WTF::StringImpl*)
7   0x10d6e8ed7 JSC::DFG::ByteCodeParser::parseBlock(unsigned int)
8   0x10d6e1629 JSC::DFG::ByteCodeParser::parseCodeBlock()
9   0x10d6ef97a JSC::DFG::ByteCodeParser::parse()
10  0x10d6efcae JSC::DFG::parse(JSC::DFG::Graph&)
11  0x10d887951 JSC::DFG::Plan::compileInThreadImpl(JSC::DFG::LongLivedState&)
12  0x10d887566 JSC::DFG::Plan::compileInThread(JSC::DFG::LongLivedState&, JSC::DFG::ThreadData*)
13  0x10d94a640 JSC::DFG::Worklist::runThread(JSC::DFG::ThreadData*)
14  0x10d948c34 JSC::DFG::Worklist::threadFunction(void*)
15  0x10defce69 WTF::createThread(void (*)(void*), void*, char const*)::$_0::operator()() const
16  0x10defce3c std::__1::__function::__func<WTF::createThread(void (*)(void*), void*, char const*)::$_0, std::__1::allocator<WTF::createThread(void (*)(void*), void*, char const*)::$_0>, void ()>::operator()()
17  0x10ded207a std::__1::function<void ()>::operator()() const
18  0x10defbdbe WTF::threadEntryPoint(void*)
19  0x10defd7c8 WTF::wtfThreadEntryPoint(void*)
20  0x7fff8cede2fc _pthread_body
21  0x7fff8cede279 _pthread_body
22  0x7fff8cedc4b1 thread_start
LEAK: 2 WebPageProxy
LEAK: 2 WebContext
Comment 1 Michael Saboff 2014-11-21 23:26:00 PST
Created attachment 242113 [details]
Comment 2 Michael Saboff 2014-11-22 11:07:11 PST
Committed r176506: <http://trac.webkit.org/changeset/176506>
Comment 3 Mark Lam 2014-11-23 08:20:27 PST
*** Bug 138772 has been marked as a duplicate of this bug. ***
Comment 4 Geoffrey Garen 2014-12-02 12:41:53 PST
Comment on attachment 242113 [details]

Can you write a test for this? I think the test case here is more valuable than the patch, since this is code that changes a lot, and this mistake can easily be reintroduced.

It looks like the key to this bug is invoking tryBuildGetByIDList(), with an object whose prototype is explicitly null.

So, you can probably get this to happen by writing a test case where we repeatedly do an access, for three or four different structures, and each structure has a null prototype.

One way to get a null prototype is to explicitly set object.__proto__ = null.
Comment 5 Geoffrey Garen 2014-12-02 12:43:54 PST
var o1 = { __proto__: null, a: 0, b: 0 };
var o2 =  { __proto__: null, a: 0, c: 0 };
var o3 =  { __proto__: null, a: 0, d: 0 };

function access(o)
    return o.a;

do a lot: