Bug 124508 - Crash when BytecodeGenerator::emitJump calls Label::bind on null pointer
Summary: Crash when BytecodeGenerator::emitJump calls Label::bind on null pointer
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC Linux
: P2 Normal
Assignee: Mark Lam
URL:
Keywords: InRadar
Depends on:
Blocks: 116980
  Show dependency treegraph
 
Reported: 2013-11-18 08:30 PST by Renata Hodovan
Modified: 2014-03-21 16:51 PDT (History)
9 users (show)

See Also:


Attachments
Test case (735 bytes, application/javascript)
2013-11-18 08:30 PST, Renata Hodovan
no flags Details
the patch. (13.49 KB, patch)
2014-03-21 16:00 PDT, Mark Lam
oliver: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Renata Hodovan 2013-11-18 08:30:53 PST
Created attachment 217201 [details]
Test case

The test below crashes on x86_64 Ubuntu 12.04. It is seems like a recursive loop, but we shouldn't even step into the switch, since var_1 is undeclared. I can reproduce it both with EFL and NIX builds.


function function_0() {

    switch (var_1) {
    case "foo":
        switch (var_1) {
        case "foo":
            switch (var_1) {
            case "foo":
                switch (var_1) {
                case var_1:
                    try {} catch (e_0) {
                        break;
                    } finally {
                        switch (var_1) {
                        case "foo":
                            label_2: 
                                    for (;;)
                                    label_3:
                                        for (;;)
                                        continue label_3;
                        }

                    }
                }
            }
        }
    }

}

function_0();

===============================================

The backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff70ab520 in JSC::Label::bind (this=0x0, opcode=157, offset=158)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/Label.h:55
55	            if (m_location == invalidLocation) {
(gdb) bt
#0  0x00007ffff70ab520 in JSC::Label::bind (this=0x0, opcode=157, offset=158)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/Label.h:55
#1  0x00007ffff70a0935 in JSC::BytecodeGenerator::emitJump (this=0x673c00, target=0x0)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:695
#2  0x00007ffff70db2c0 in JSC::BreakNode::emitBytecode (this=0x670548, generator=...)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1900
#3  0x00007ffff70ac827 in JSC::BytecodeGenerator::emitNode (this=0x673c00, dst=0x673c58, n=0x670548)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:240
#4  0x00007ffff70e02d5 in JSC::SourceElements::emitBytecode (this=0x670530, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1504
#5  0x00007ffff70d8fb0 in JSC::BlockNode::emitBytecode (this=0x670590, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1523
#6  0x00007ffff70ac827 in JSC::BytecodeGenerator::emitNode (this=0x673c00, dst=0x673c58, n=0x670590)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:240
#7  0x00007ffff70dc967 in JSC::TryNode::emitBytecode (this=0x670808, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2175
#8  0x00007ffff70ac827 in JSC::BytecodeGenerator::emitNode (this=0x673c00, dst=0x673c58, n=0x670808)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:240
#9  0x00007ffff70e02d5 in JSC::SourceElements::emitBytecode (this=0x6704f8, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1504
#10 0x00007ffff70e038c in JSC::CaseClauseNode::emitBytecode (this=0x670840, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1942
#11 0x00007ffff70dc05a in JSC::CaseBlockNode::emitBytecodeForBlock (this=0x670860, generator=..., switchExpression=0x673770, dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2075
#12 0x00007ffff70dc3f6 in JSC::SwitchNode::emitBytecode (this=0x670878, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2106
#13 0x00007ffff70ac827 in JSC::BytecodeGenerator::emitNode (this=0x673c00, dst=0x673c58, n=0x670878)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:240
#14 0x00007ffff70e02d5 in JSC::SourceElements::emitBytecode (this=0x670480, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1504
#15 0x00007ffff70e038c in JSC::CaseClauseNode::emitBytecode (this=0x6708a0, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1942
#16 0x00007ffff70dc05a in JSC::CaseBlockNode::emitBytecodeForBlock (this=0x6708c0, generator=..., switchExpression=0x673758, dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2075
#17 0x00007ffff70dc3f6 in JSC::SwitchNode::emitBytecode (this=0x6708d8, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2106
#18 0x00007ffff70ac827 in JSC::BytecodeGenerator::emitNode (this=0x673c00, dst=0x673c58, n=0x6708d8)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:240
#19 0x00007ffff70e02d5 in JSC::SourceElements::emitBytecode (this=0x670418, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1504
#20 0x00007ffff70e038c in JSC::CaseClauseNode::emitBytecode (this=0x670900, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1942
#21 0x00007ffff70dc05a in JSC::CaseBlockNode::emitBytecodeForBlock (this=0x670920, generator=..., switchExpression=0x673740, dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2075
#22 0x00007ffff70dc3f6 in JSC::SwitchNode::emitBytecode (this=0x670938, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2106
#23 0x00007ffff70ac827 in JSC::BytecodeGenerator::emitNode (this=0x673c00, dst=0x673c58, n=0x670938)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:240
#24 0x00007ffff70e02d5 in JSC::SourceElements::emitBytecode (this=0x6703b0, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1504
#25 0x00007ffff70e038c in JSC::CaseClauseNode::emitBytecode (this=0x670960, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1942
#26 0x00007ffff70dc05a in JSC::CaseBlockNode::emitBytecodeForBlock (this=0x670980, generator=..., switchExpression=0x673728, dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2075
---Type <return> to continue, or q <return> to quit---
#27 0x00007ffff70dc3f6 in JSC::SwitchNode::emitBytecode (this=0x670998, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2106
#28 0x00007ffff70ac827 in JSC::BytecodeGenerator::emitNode (this=0x673c00, dst=0x673c58, n=0x670998)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:240
#29 0x00007ffff70e02d5 in JSC::SourceElements::emitBytecode (this=0x670348, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1504
#30 0x00007ffff70d8fb0 in JSC::BlockNode::emitBytecode (this=0x6709c0, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1523
#31 0x00007ffff70ac827 in JSC::BytecodeGenerator::emitNode (this=0x673c00, dst=0x673c58, n=0x6709c0)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:240
#32 0x00007ffff70e02d5 in JSC::SourceElements::emitBytecode (this=0x670330, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1504
#33 0x00007ffff70e03d4 in JSC::ScopeNode::emitStatementsBytecode (this=0x6722e0, generator=..., dst=0x673c58)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2206
#34 0x00007ffff70dce86 in JSC::FunctionBodyNode::emitBytecode (this=0x6722e0, generator=...)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2242
#35 0x00007ffff709d41d in JSC::BytecodeGenerator::generate (this=0x673c00)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:65
#36 0x00007ffff7094aa5 in JSC::generateFunctionCodeBlock (vm=..., executable=0x7ffff7f874e0, source=..., kind=JSC::CodeForCall, 
    debuggerMode=JSC::DebuggerOff, profilerMode=JSC::ProfilerOff, error=...)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp:66
#37 0x00007ffff709531e in JSC::UnlinkedFunctionExecutable::codeBlockFor (this=0x7ffff7f874e0, vm=..., source=..., 
    specializationKind=JSC::CodeForCall, debuggerMode=JSC::DebuggerOff, profilerMode=JSC::ProfilerOff, error=...)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp:161
#38 0x00007ffff73d32fc in JSC::ScriptExecutable::newCodeBlockFor (this=0x7fffa9a5fe70, kind=JSC::CodeForCall, scope=0x7ffff7f2f970, 
    exception=@0x7fffffffcc80: 0x0) at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/runtime/Executable.cpp:211
#39 0x00007ffff73d3989 in JSC::ScriptExecutable::prepareForExecutionImpl (this=0x7fffa9a5fe70, exec=0x7fffa9ebff30, scope=0x7ffff7f2f970, 
    kind=JSC::CodeForCall) at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/runtime/Executable.cpp:293
#40 0x00007ffff72a934c in JSC::ScriptExecutable::prepareForExecution (this=0x7fffa9a5fe70, exec=0x7fffa9ebff30, scope=0x7ffff7f2f970, 
    kind=JSC::CodeForCall) at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/runtime/Executable.h:415
#41 0x00007ffff74ff7e9 in JSC::LLInt::setUpCall (execCallee=0x7fffa9ebff30, pc=0x6733b0, kind=JSC::CodeForCall, calleeAsValue=..., 
    callLinkInfo=0x656b30) at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:1043
#42 0x00007ffff74ffc08 in JSC::LLInt::genericCall (exec=0x7fffa9ebff78, pc=0x6733b0, kind=JSC::CodeForCall)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:1090
#43 0x00007ffff74fc101 in JSC::LLInt::llint_slow_path_call (exec=0x7fffa9ebff78, pc=0x6733b0)
    at /home/reni2/data/REPOS/webkit/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:1096
#44 0x00007ffff7503d7f in llint_op_call () from /home/reni2/data/REPOS/webkit/WebKitBuild/Debug/lib/libjavascriptcore_efl.so.0
#45 0x00007fffaa6c2920 in ?? ()
#46 0x00000000006571b8 in ?? ()
#47 0x0000000000000000 in ?? ()
Comment 1 David Kilzer (:ddkilzer) 2013-11-23 16:00:19 PST
<rdar://problem/15543174>
Comment 2 Mark Lam 2014-03-21 16:00:54 PDT
Created attachment 227503 [details]
the patch.
Comment 3 Oliver Hunt 2014-03-21 16:10:46 PDT
Comment on attachment 227503 [details]
the patch.

View in context: https://bugs.webkit.org/attachment.cgi?id=227503&action=review

r+ with operator! vs. bool fixed

> Source/JavaScriptCore/bytecompiler/LabelScope.h:121
> +

i would prefer operator! or at the very least make this explicit other c++ can use this to convert to ints, which has historically been a source of much pain
Comment 4 Mark Lam 2014-03-21 16:23:50 PDT
(In reply to comment #3)
> (From update of attachment 227503 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=227503&action=review
> 
> r+ with operator! vs. bool fixed
> 
> > Source/JavaScriptCore/bytecompiler/LabelScope.h:121
> > +
> 
> i would prefer operator! or at the very least make this explicit other c++ can use this to convert to ints, which has historically been a source of much pain

Thanks.  Will implement operator!.  There's also a bug in the new test files.  All the file content has been duplicated.  I'll removed the duplication before committing.
Comment 5 Geoffrey Garen 2014-03-21 16:26:44 PDT
Comment on attachment 227503 [details]
the patch.

Why do we use LabelScopePtr for LabelScopes, and RefPtr to SegmentedVector for other things?

Seems like we should choose one solution or the other -- and the SegmentedVector solution involves a lot less boilerplate code.
Comment 6 Mark Lam 2014-03-21 16:28:46 PDT
(In reply to comment #5)
> (From update of attachment 227503 [details])
> Why do we use LabelScopePtr for LabelScopes, and RefPtr to SegmentedVector for other things?
> 
> Seems like we should choose one solution or the other -- and the SegmentedVector solution involves a lot less boilerplate code.

In BytecodeGenerator::emitComplexPopScopes(), we need to make a copy of m_localScopes in order to preserve it while we emit bytecode for finally clause handling.  The SegmentedVector explicitly does not allow copying.  That's why I stuck with using the LocalScopePtr.
Comment 7 Mark Lam 2014-03-21 16:51:02 PDT
Fix landed in r166107: <http://trac.webkit.org/r166107>.

We may revisit the fix later if needed and switch to using SegmentedVector instead of LocalScopePtr.  To be determined.