ponyc: Segfault on Linux at runtime.

It’s curious that it doesn’t seem to occur on playground, but here’s the listing:

use "debug"

actor Main
  new create(env: Env) =>
    let a: AA = AA
    inspecta(consume a)

  be inspecta(a: AA val) =>
    Debug.out("in inspecta")


struct iso AA

If you change the receiver refcap from val to iso or tag it executes fine.

Here’s the backtrace with val:

[nix-shell:~/projects/pony/test]$ lldb ./test
(lldb) target create "./test"
Current executable set to './test' (x86_64).
(lldb) run
Process 24552 launched: '/home/red/projects/pony/test/test' (x86_64)
Process 24552 stopped
* thread #2, name = 'test', stop reason = signal SIGSEGV: invalid address (fault address: 0x18)
    frame #0: 0x000000000040cf6a test`ponyint_gc_markimmutable + 106
test`ponyint_gc_markimmutable:
->  0x40cf6a <+106>: movq   0x18(%r13), %r13
    0x40cf6e <+110>: testq  %r13, %r13
    0x40cf71 <+113>: je     0x40cfa0                  ; <+160>
    0x40cf73 <+115>: movq   0x20(%r14), %rdi
(lldb) bt
* thread #2, name = 'test', stop reason = signal SIGSEGV: invalid address (fault address: 0x18)
  * frame #0: 0x000000000040cf6a test`ponyint_gc_markimmutable + 106
    frame #1: 0x000000000040e4b8 test`ponyint_mark_done + 24
    frame #2: 0x0000000000408b02 test`ponyint_actor_run + 242
    frame #3: 0x000000000041181f test`run_thread + 447
    frame #4: 0x00007ffff7fb3e9e libpthread.so.0`start_thread + 206
    frame #5: 0x00007ffff7d7749f libc.so.6`__GI___clone + 63

Any advice on how to proceed welcomed.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 23 (23 by maintainers)

Most upvoted comments

@redvers I strongly disagree with…

Re-writing Pointer as a class seems like a poor candidate for Risk <–> Reward for a bug that took almost 10 years for someone to stumble across.

This is a runtime crash that happened to be on a path that no one exercised until now. It could have happened to anyone at any point and still can. Runtime crashes are bad and destroy the primary proposition of safety for Pony. It needs to be fixed and the other options are worse in terms of the Pony Philosophy.

  • Changing Pointer to be a class have zero impact on user code if we do it correctly.
  • Changes to not all ref types on structs would potentially break some user code but only if they are doing struct tag as pretty much everything else should be crashing (and so probably doesn’t exist)

One of the key points of the Pony philosophy is that we should make the implementation of the compiler/runtime harder to maintain if that has serious benefits to the users. And in this case, not touching object map has serious wins for all Pony users/programs.

It’s some work to fix this with the proposed solution, but I think it is far and away the best fix and we can not leave this bug unfixed. Runtime crashes are unacceptable.