Skip to content

[Kernel] Crash with 'correct' arguments #29135

@jensjoha

Description

@jensjoha
Contributor

Given helloworld.dart:

main() {
  print("Hello, World!");
}

running with

out/ReleaseX64/dart --no-prune-dead-locals --no-background-compilation --optimization-counter-threshold=10 --dfe=out/ReleaseX64/gen/kernel-service.dart.snapshot --packages=.packages helloworld.dart 

gives me

Dumping native stack trace for thread 579b
  [0x000000000074b3a0] dart::CompileType::Union(dart::CompileType*)
  [0x000000000074b3a0] dart::CompileType::Union(dart::CompileType*)
  [0x000000000074c062] dart::PhiInstr::RecomputeType()
  [0x00000000007491f1] dart::FlowGraphTypePropagator::Propagate()
  [0x0000000000748f66] dart::FlowGraphTypePropagator::Propagate(dart::FlowGraph*)
  [0x00000000006b4a74] dart::CompileParsedFunctionHelper::Compile(dart::CompilationPipeline*)
  [0x00000000006b5de2] Unknown symbol
  [0x00000000006b6c56] dart::Compiler::CompileOptimizedFunction(dart::Thread*, dart::Function const&, long)
  [0x00000000009af909] dart::DRT_OptimizeInvokedFunction(dart::NativeArguments)
  [0x00007fbfc24b261b] Unknown symbol
  [0x00007fbfc24b2911] Unknown symbol
  [0x00007fbfb7a444de] Unknown symbol
  [0x00007fbfc24b29d9] Unknown symbol
-- End of DumpStackTrace
Aborted (core dumped)

and running with

out/DebugX64/dart --no-prune-dead-locals --no-background-compilation --optimization-counter-threshold=10 --dfe=out/DebugX64/gen/kernel-service.dart.snapshot --packages=.packages helloworld.dart

gives me

../../runtime/vm/flow_graph.cc: 345: error: expected: (defn->input_use_list() == NULL) || defn->HasSSATemp()
Dumping native stack trace for thread 5897
  [0x00000000009b6e03] dart::Profiler::DumpStackTrace()
  [0x00000000009b6e03] dart::Profiler::DumpStackTrace()
  [0x0000000000692ba1] dart::DynamicAssertionHelper::Fail(char const*, ...)
  [0x000000000073d7b7] Unknown symbol
  [0x000000000073d308] dart::FlowGraph::VerifyUseLists()
  [0x00000000006f9c75] dart::CompileParsedFunctionHelper::Compile(dart::CompilationPipeline*)
  [0x00000000006fbf63] Unknown symbol
  [0x00000000006fcde9] dart::Compiler::CompileOptimizedFunction(dart::Thread*, dart::Function const&, long)
  [0x00000000006ee5a9] dart::DRT_OptimizeInvokedFunction(dart::NativeArguments)
  [0x00007ff4a6b01630] Unknown symbol
  [0x00007ff4a6b01971] Unknown symbol
  [0x00007ff49bec0bd7] Unknown symbol
  [0x00007ff4a6b01a4e] Unknown symbol
-- End of DumpStackTrace
Aborted (core dumped)

Activity

changed the title [-][Kernel] Crash with [/-] [+][Kernel] Crash with 'correct' arguments[/+] on Mar 22, 2017
jensjoha

jensjoha commented on Mar 24, 2017

@jensjoha
ContributorAuthor

I've tried to look into this, and so far this is what I've found:

In core/uri.dart function "static Uri parse(String uri, [int start = 0, int end])"

    indices
      ..[0] = 0
      ..[_schemeEndIndex] = start - 1
      ..[_hostStartIndex] = start - 1
      ..[_notSimpleIndex] = start - 1
      ..[_portStartIndex] = start
      ..[_pathStartIndex] = start
      ..[_queryStartIndex] = end
      ..[_fragmentStartIndex] = end;

in ssa becomes

    PushArgument(v20)
    PushArgument(v21)
    v22 <- StaticCall:118( List._internal@0150898 v20, v21)
    PushArgument(v22)
    PushArgument(v24)
    PushArgument(v24)
    v25 <- InstanceCall:120( []=, v22, v24, v24 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    PushArgument(v22)
    PushArgument(v27)
    PushArgument(v4)
    PushArgument(v27)
    v28 <- InstanceCall:122( -, v4, v27 IC[1: _Smi@0150898, _Smi@0150898 cnt:1 trgt:'_IntegerImplementation@0150898.-'])
    PushArgument(v28)
    v30 <- InstanceCall:124( []=, v22, v27, v28 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    PushArgument(v22)
    PushArgument(v32)
    PushArgument(v4)
    PushArgument(v27)
    v33 <- InstanceCall:126( -, v4, v27 IC[1: _Smi@0150898, _Smi@0150898 cnt:1 trgt:'_IntegerImplementation@0150898.-'])
    PushArgument(v33)
    v35 <- InstanceCall:128( []=, v22, v32, v33 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    PushArgument(v22)
    PushArgument(v37)
    PushArgument(v4)
    PushArgument(v27)
    v38 <- InstanceCall:130( -, v4, v27 IC[1: _Smi@0150898, _Smi@0150898 cnt:1 trgt:'_IntegerImplementation@0150898.-'])
    PushArgument(v38)
    v40 <- InstanceCall:132( []=, v22, v37, v38 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    PushArgument(v22)
    PushArgument(v42)
    PushArgument(v4)
    v43 <- InstanceCall:134( []=, v22, v42, v4 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    PushArgument(v22)
    PushArgument(v45)
    PushArgument(v4)
    v46 <- InstanceCall:136( []=, v22, v45, v4 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    PushArgument(v22)
    PushArgument(v13)
    PushArgument(v9)
    v48 <- InstanceCall:138( []=, v22, v13, v9 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    PushArgument(v22)
    PushArgument(v50)
    PushArgument(v9)
    v51 <- InstanceCall:140( []=, v22, v50, v9 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])

which then after

        JitOptimizer optimizer(flow_graph);
        optimizer.ApplyICData();

in CompileParsedFunctionHelper::Compile in file runtime/vm/compiler.cc becomes

    PushArgument(v20)
    PushArgument(v21)
    v22 <- StaticCall:118( List._internal@0150898 v20, v21)
    CheckClass:120(v22 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    v798 <- LoadField(v22, 16, immutable=1)
    CheckArrayBound:120(v798, v24)
    StoreIndexed:120(v22, v24, v24)
    CheckSmi:122(v4)
    v28 <- BinarySmiOp:122(-, v4, v27)
    CheckClass:124(v22 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    v800 <- LoadField(v22, 16, immutable=1)
    CheckArrayBound:124(v800, v27)
    StoreIndexed:124(v22, v27, v28)
    CheckSmi:126(v4)
    v33 <- BinarySmiOp:126(-, v4, v27)
    CheckClass:128(v22 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    v802 <- LoadField(v22, 16, immutable=1)
    CheckArrayBound:128(v802, v32)
    StoreIndexed:128(v22, v32, v33)
    CheckSmi:130(v4)
    v38 <- BinarySmiOp:130(-, v4, v27)
    CheckClass:132(v22 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    v804 <- LoadField(v22, 16, immutable=1)
    CheckArrayBound:132(v804, v37)
    StoreIndexed:132(v22, v37, v38)
    CheckClass:134(v22 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    v806 <- LoadField(v22, 16, immutable=1)
    CheckArrayBound:134(v806, v42)
    StoreIndexed:134(v22, v42, v4)
    CheckClass:136(v22 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    v808 <- LoadField(v22, 16, immutable=1)
    CheckArrayBound:136(v808, v45)
    StoreIndexed:136(v22, v45, v4)
    CheckClass:138(v22 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    v810 <- LoadField(v22, 16, immutable=1)
    CheckArrayBound:138(v810, v13)
    StoreIndexed:138(v22, v13, v9)
    CheckClass:140(v22 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])
    v812 <- LoadField(v22, 16, immutable=1)
    CheckArrayBound:140(v812, v50)
    StoreIndexed:140(v22, v50, v9)

where for instance

v25 <- InstanceCall:120( []=, v22, v24, v24 IC[1: _List@0150898 cnt:1 trgt:'_List@0150898.[]='])

is replaced by

StoreIndexed:120(v22, v24, v24)

--- the problem being that v25 is used later where e.g.

v629 <- phi(v636, v25) alive

becomes

v629 <- phi(v636, ) alive

which doesn't seem right... (in total it seems to be used 7 times)

I can't really seem to figure out what's causing it though.

jensjoha

jensjoha commented on Mar 24, 2017

@jensjoha
ContributorAuthor

Giving up...
/cc @mraleph @mkustermann

self-assigned this
on Mar 24, 2017
mraleph

mraleph commented on Mar 24, 2017

@mraleph
Member

I will take a look. From the symptoms it seems that environment position on one path is empty and on a different path it is occupied - which should not really ever happen. Prune dead locals probably hide the issue because this position is not alive. Probably graph misconstruction.

mraleph

mraleph commented on Mar 24, 2017

@mraleph
Member

Results of calls like []= should never be used because these calls don't return anything meaningful. Instead rhs value should be stored in a temporary and returned after the call.

mraleph

mraleph commented on Mar 24, 2017

@mraleph
Member

Currently Fasta translates cascade of indexed assignments into a cascade of
let-statements.

For example code like

  indices
    ..[0] = 0
    ..[_schemeEndIndex] = start - 1
    ..[_hostStartIndex] = start - 1
    ..[_notSimpleIndex] = start - 1
    ..[_portStartIndex] = start
    ..[_pathStartIndex] = start
    ..[_queryStartIndex] = end
    ..[_fragmentStartIndex] = end;

gets translated to

  let final dynamic #t826 = indices in
    let final dynamic #t827 = #t826.[]=(0, 0) in
      let final dynamic #t828 = #t826.[]=(core::_schemeEndIndex, start.-(1)) in
        let final dynamic #t829 = #t826.[]=(core::_hostStartIndex, start.-(1)) in
          let final dynamic #t830 = #t826.[]=(core::_notSimpleIndex, start.-(1)) in
            let final dynamic #t831 = #t826.[]=(core::_portStartIndex, start) in
              let final dynamic #t832 = #t826.[]=(core::_pathStartIndex, start) in
                let final dynamic #t833 = #t826.[]=(core::_queryStartIndex, end) in
                  let final dynamic #t834 = #t826.[]=(core::_fragmentStartIndex, end) in
                    #t826;

This later becomes in IL (on the example of #t826.[]=(0, 0)):

    t0 <- InstanceCall:120( []=, t0, t0, t0)
    StoreLocal(:var1 @-19, t0)

After SSA construction if locals liveness analysis is disabled (--no-prune-dead-locals) we get essentially redundant phis constructed for temporary let-variables which actually use result of the instance call:

    v25 <- InstanceCall:120( []=, v22, v24, v24)
...
    v629 <- phi(v636, v25)

These phis are redundant because their values can never be observed by the program because they correspond to dead stores. In fact these phis only have environment uses.

However subsequent optimization passes assume that result of a v.[]=(...) invocation can never be used and replace v.[]=(...) with IL sequences that don't actually produce any value - leading to malformed graphs where phis refer to instructions outside of the graph.

To workaround the issue we explicitly drop the actual result of v.[]=(...) and push a null-value to be used instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @kevmoo@mraleph@kmillikin@jensjoha

      Issue actions

        [Kernel] Crash with 'correct' arguments · Issue #29135 · dart-lang/sdk