ponylang / ponyc

Pony is an open-source, actor-model, capabilities-secure, high performance programming language
http://www.ponylang.io
BSD 2-Clause "Simplified" License
5.71k stars 415 forks source link

Segfault in ponyc gen_try #2935

Open pdtwonotes opened 5 years ago

pdtwonotes commented 5 years ago

Compliling a rather complex program gets this fault. I need help in narrowing down which piece of source code is triggering it.

Generating
 Reachability
 Selector painting
 Data prototypes
 Data types
 Function prototypes
 Functions
Process 13179 stopped
* thread #1: tid = 13179, 0x000055555567ece7 ponyc`gen_try(c=0x00007fffffffdd70, ast=0x00007ffff2a78d00) + 269 at gencontrol.c:620, name = 'ponyc', stop reason = signal SIGSEGV: invalid address (fault address: 0x88)
    frame #0: 0x000055555567ece7 ponyc`gen_try(c=0x00007fffffffdd70, ast=0x00007ffff2a78d00) + 269 at gencontrol.c:620
   617    if(needed && !ast_checkflag(ast, AST_FLAG_JUMPS_AWAY))
   618    {
   619      ast_t* type = deferred_reify(reify, ast_type(ast), c->opt);
-> 620      phi_type = (compile_type_t*)reach_type(c->reach, type)->c_type;
   621      ast_free_unattached(type);
   622    }
   623  

(lldb) bt
* thread #1: tid = 13179, 0x000055555567ece7 ponyc`gen_try(c=0x00007fffffffdd70, ast=0x00007ffff2a78d00) + 269 at gencontrol.c:620, name = 'ponyc', stop reason = signal SIGSEGV: invalid address (fault address: 0x88)
  * frame #0: 0x000055555567ece7 ponyc`gen_try(c=0x00007fffffffdd70, ast=0x00007ffff2a78d00) + 269 at gencontrol.c:620
    frame #1: 0x0000555555604e9f ponyc`gen_expr(c=0x00007fffffffdd70, ast=0x00007ffff2a78d00) + 457 at genexpr.c:84
    frame #2: 0x000055555567a5d9 ponyc`gen_assign(c=0x00007fffffffdd70, ast=0x00007ffff2a77100) + 96 at genoperator.c:927
    frame #3: 0x0000555555605061 ponyc`gen_expr(c=0x00007fffffffdd70, ast=0x00007ffff2a77100) + 907 at genexpr.c:147
    frame #4: 0x000055555567cfd9 ponyc`gen_seq(c=0x00007fffffffdd70, ast=0x00007ffff2a77080) + 78 at gencontrol.c:22
    frame #5: 0x0000555555604d5e ponyc`gen_expr(c=0x00007fffffffdd70, ast=0x00007ffff2a77080) + 136 at genexpr.c:26
    frame #6: 0x000055555567db33 ponyc`gen_while(c=0x00007fffffffdd70, ast=0x00007ffff2a77b80) + 812 at gencontrol.c:248
    frame #7: 0x0000555555604e67 ponyc`gen_expr(c=0x00007fffffffdd70, ast=0x00007ffff2a77b80) + 401 at genexpr.c:75
    frame #8: 0x000055555567cfd9 ponyc`gen_seq(c=0x00007fffffffdd70, ast=0x00007ffff2a77900) + 78 at gencontrol.c:22
    frame #9: 0x0000555555604d5e ponyc`gen_expr(c=0x00007fffffffdd70, ast=0x00007ffff2a77900) + 136 at genexpr.c:26
    frame #10: 0x000055555567cfd9 ponyc`gen_seq(c=0x00007fffffffdd70, ast=0x00007ffff2a91600) + 78 at gencontrol.c:22
    frame #11: 0x0000555555604d5e ponyc`gen_expr(c=0x00007fffffffdd70, ast=0x00007ffff2a91600) + 136 at genexpr.c:26
    frame #12: 0x0000555555674b7e ponyc`genfun_new(c=0x00007fffffffdd70, t=0x00007fffdc888800, m=0x00007fffdc888e80) + 349 at genfun.c:552
    frame #13: 0x0000555555675810 ponyc`genfun_method(c=0x00007fffffffdd70, t=0x00007fffdc888800, n=0x00007fffdc888e00, m=0x00007fffdc888e80) + 302 at genfun.c:786
    frame #14: 0x0000555555675d62 ponyc`genfun_method_bodies(c=0x00007fffffffdd70, t=0x00007fffdc888800) + 107 at genfun.c:949
    frame #15: 0x0000555555668572 ponyc`gentypes(c=0x00007fffffffdd70) + 1111 at gentype.c:962
    frame #16: 0x0000555555608a2b ponyc`genexe(c=0x00007fffffffdd70, program=0x00007ffff33c4d80) + 718 at genexe.c:534
    frame #17: 0x00005555555fc98d ponyc`codegen(program=0x00007ffff33c4d80, opt=0x00007fffffffe250) + 342 at codegen.c:875
    frame #18: 0x000055555559f115 ponyc`generate_passes(program=0x00007ffff33c4d80, options=0x00007fffffffe250) + 53 at pass.c:360
    frame #19: 0x000055555559d96f ponyc`compile_package(path="src/ag-movies", opt=0x00007fffffffe250, print_program_ast=false, print_package_ast=false) + 167 at main.c:67
    frame #20: 0x000055555559db54 ponyc`main(argc=2, argv=0x00007fffffffe408) + 459 at main.c:112
    frame #21: 0x00007ffff3cacb97 libc.so.6`__libc_start_main(main=(ponyc`main at main.c:73), argc=4, argv=0x00007fffffffe408, init=<unavailable>, fini=<unavailable>, rtld_fini=<unavailable>, stack_end=0x00007fffffffe3f8) + 231 at libc-start.c:310
    frame #22: 0x000055555559d76a ponyc`_start + 42
mfelsche commented 5 years ago

Thanks for reporting this. Could you print both the ast and type variables when you reached the segfault in the debugger with: p ast_print(ast, 80) p ast_print(type, 80) and paste them here?

That would be mighty helpful.

pdtwonotes commented 5 years ago
(lldb) p ast_print(ast,80)
(try
  (seq:scope
    (call
      (funref
        (letref (id $2$0) [nominal (id $3) (id BRPairIterator) x ref x x])
        (id next)
        [funtype
          ref
          x
          x
          (tupletype
            (uniontype
              (nominal (id $0) (id U8) x val x x)
              (nominal (id $0) (id U16) x val x x)
              (nominal (id $0) (id U32) x val x x)
              (nominal (id $0) (id USize) x val x x)
              (nominal (id $0) (id String) x val x x)
              (nominal (id $0) (id String) x val x x)
              (nominal
                (id $0)
                (id Array)
                (typeargs (nominal (id $0) (id U8) x val x x))
                val
                x
                x
              )
              (nominal (id $0) (id None) x val x x)
            )
            (uniontype
              (nominal (id $0) (id U8) x val x x)
              (nominal (id $0) (id U16) x val x x)
              (nominal (id $0) (id U32) x val x x)
              (nominal (id $0) (id USize) x val x x)
              (nominal (id $0) (id String) x val x x)
              (nominal (id $0) (id String) x val x x)
              (nominal
                (id $0)
                (id Array)
                (typeargs (nominal (id $0) (id U8) x val x x))
                val
                x
                x
              )
              (nominal (id $0) (id None) x val x x)
            )
          )
        ]
      )
      x
      x
      ?
      [tupletype
        (uniontype
          (nominal (id $0) (id U8) x val x x)
          (nominal (id $0) (id U16) x val x x)
          (nominal (id $0) (id U32) x val x x)
          (nominal (id $0) (id USize) x val x x)
          (nominal (id $0) (id String) x val x x)
          (nominal (id $0) (id String) x val x x)
          (nominal
            (id $0)
            (id Array)
            (typeargs (nominal (id $0) (id U8) x val x x))
            val
            x
            x
          )
          (nominal (id $0) (id None) x val x x)
        )
        (uniontype
          (nominal (id $0) (id U8) x val x x)
          (nominal (id $0) (id U16) x val x x)
          (nominal (id $0) (id U32) x val x x)
          (nominal (id $0) (id USize) x val x x)
          (nominal (id $0) (id String) x val x x)
          (nominal (id $0) (id String) x val x x)
          (nominal
            (id $0)
            (id Array)
            (typeargs (nominal (id $0) (id U8) x val x x))
            val
            x
            x
          )
          (nominal (id $0) (id None) x val x x)
        )
      ]
    )
    [tupletype
      (uniontype
        (nominal (id $0) (id U8) x val x x)
        (nominal (id $0) (id U16) x val x x)
        (nominal (id $0) (id U32) x val x x)
        (nominal (id $0) (id USize) x val x x)
        (nominal (id $0) (id String) x val x x)
        (nominal (id $0) (id String) x val x x)
        (nominal
          (id $0)
          (id Array)
          (typeargs (nominal (id $0) (id U8) x val x x))
          val
          x
          x
        )
        (nominal (id $0) (id None) x val x x)
      )
      (uniontype
        (nominal (id $0) (id U8) x val x x)
        (nominal (id $0) (id U16) x val x x)
        (nominal (id $0) (id U32) x val x x)
        (nominal (id $0) (id USize) x val x x)
        (nominal (id $0) (id String) x val x x)
        (nominal (id $0) (id String) x val x x)
        (nominal
          (id $0)
          (id Array)
          (typeargs (nominal (id $0) (id U8) x val x x))
          val
          x
          x
        )
        (nominal (id $0) (id None) x val x x)
      )
    ]
  )
  (seq:scope (break x))
  (seq:scope
    (call
      (newref
        (typeref x (id None) x [nominal (id $0) (id None) x val x x])
        (id create)
        [funtype val x x (nominal (id $0) (id None) x val ^ x)]
      )
      x
      x
      x
      [nominal (id $0) (id None) x val ^ x]
    )
    [nominal (id $0) (id None) x val ^ x]
  )
  [tupletype
    (uniontype
      (nominal (id $0) (id U8) x val x x)
      (nominal (id $0) (id U16) x val x x)
      (nominal (id $0) (id U32) x val x x)
      (nominal (id $0) (id USize) x val x x)
      (nominal (id $0) (id String) x val x x)
      (nominal (id $0) (id String) x val x x)
      (nominal
        (id $0)
        (id Array)
        (typeargs (nominal (id $0) (id U8) x val x x))
        val
        x
        x
      )
      (nominal (id $0) (id None) x val x x)
    )
    (uniontype
      (nominal (id $0) (id U8) x val x x)
      (nominal (id $0) (id U16) x val x x)
      (nominal (id $0) (id U32) x val x x)
      (nominal (id $0) (id USize) x val x x)
      (nominal (id $0) (id String) x val x x)
      (nominal (id $0) (id String) x val x x)
      (nominal
        (id $0)
        (id Array)
        (typeargs (nominal (id $0) (id U8) x val x x))
        val
        x
        x
      )
      (nominal (id $0) (id None) x val x x)
    )
  ]
)

(lldb) p ast_print(type,80)
(tupletype
  (uniontype
    (nominal (id $0) (id U8) x val x x)
    (nominal (id $0) (id U16) x val x x)
    (nominal (id $0) (id U32) x val x x)
    (nominal (id $0) (id USize) x val x x)
    (nominal (id $0) (id String) x val x x)
    (nominal (id $0) (id String) x val x x)
    (nominal
      (id $0)
      (id Array)
      (typeargs (nominal (id $0) (id U8) x val x x))
      val
      x
      x
    )
    (nominal (id $0) (id None) x val x x)
  )
  (uniontype
    (nominal (id $0) (id U8) x val x x)
    (nominal (id $0) (id U16) x val x x)
    (nominal (id $0) (id U32) x val x x)
    (nominal (id $0) (id USize) x val x x)
    (nominal (id $0) (id String) x val x x)
    (nominal (id $0) (id String) x val x x)
    (nominal
      (id $0)
      (id Array)
      (typeargs (nominal (id $0) (id U8) x val x x))
      val
      x
      x
    )
    (nominal (id $0) (id None) x val x x)
  )
)
pdtwonotes commented 5 years ago

I suspect that this might be because I have a union type that contains both String and ByteSeq. And ByteSeq itself is a union type containing String and Array[U8]. This results in two copies of String in my union type. When I change my code to not have both String and ByteSeq, the segment violation goes away. Perhaps this case needs to be caught before getting to code generation with the usual helpful error message.