Ticket #956 (closed bug: fixed)

Opened 5 years ago

Last modified 3 years ago

Singleton PMCs with the active_destroy flag set cause segfaults when collected

Reported by: darbelo Owned by:
Priority: normal Milestone:
Component: GC Version: trunk
Severity: medium Keywords: gc segfault dynpmcs
Cc: Language:
Patch status: Platform: all


Here's an example dynpmc, called SegFaulty, drop the attached .pmc into src/dynpmcs/ and add it to the Makefile there (a simple s/dynlexpad/segfaulty/g should suffice) to build it. Parrot will segfault when the pmc is collected.

Not setting PObj_active_destroy_SET(SELF) on the PMC avoids the segfault.

As an example:

$ pwd
$ cat example.pir
.sub segfault :main
    $P0 = loadlib 'segfaulty'
    $P1 = new "SegFaulty"

    say 'Nothing wrong here.'

$ ../../parrot example.pir
Nothing wrong here.
Segmentation fault (core dumped) 

Examining that core dump with gdb yields the following backtrace:

(gdb) bt
#0  0x00000002050f61f0 in ?? ()
#1  0x00000002079a9395 in Parrot_pmc_destroy (interp=0x20178a400, pmc=0x20b5042d0) at src/pmc.c:113
#2  0x000000020795b24c in free_pmc_in_pool (interp=0x20178a400, pool_unused=0x202d35b00, 
    p=0x20b5042d0) at src/gc/mark_sweep.c:781
#3  0x000000020795a68d in Parrot_gc_sweep_pool (interp=0x20178a400, pool=0x202d35b00)
    at src/gc/mark_sweep.c:342
#4  0x0000000207959715 in gc_ms_finalize (interp=0x20178a400, arena_base=0x202d35400)
    at src/gc/gc_ms.c:234
#5  0x00000002079594f7 in gc_ms_mark_and_sweep (interp=0x20178a400, flags=4) at src/gc/gc_ms.c:160
#6  0x0000000207956c3d in Parrot_gc_mark_and_sweep (interp=0x20178a400, flags=4) at src/gc/api.c:805
#7  0x0000000207968e99 in Parrot_really_destroy (interp=0x20178a400, exit_code_unused=0, 
    arg_unused=0x0) at src/interp/inter_create.c:350
#8  0x0000000207947734 in Parrot_exit (interp=0x20178a400, status=0) at src/exit.c:91
#9  0x0000000000400ecf in main (argc=1, argv=0x7f7ffffddfc8) at src/main.c:65


segfaulty.pmc Download (0.6 KB) - added by darbelo 5 years ago.
Example segfaulty PMC

Change History

Changed 5 years ago by darbelo

Example segfaulty PMC

in reply to: ↑ description   Changed 5 years ago by darbelo

I forgot to add: removing the destroy VTABLE (in effect, calling the default one) will cause the segfault to disappear as well, even with active_destroy set.

  Changed 5 years ago by whiteknight

As a matter of some explanation, chromatic suggested (and I agree with him) this chain of events:

  • The dynpmc library is loaded, a Constant Library PMC is created for it.
  • The SegFaulty PMC is loaded. It's a singleton, so it goes into the Constant PMC pool too.
  • On finalization, the Library PMC is freed first and the SegFaulty PMC is freed second. However, calling SegFaulty.destroy() segfaults becase SURPRISE the library has already been unloaded and the function pointer doesn't point to a function that exists anymore
  • Hilarity ensues

I haven't tested that this is exactly what does happen, just a very plausible explanation.

  Changed 5 years ago by jkeenan

  • summary changed from [gc] Singleton PMCs with the active_destroy flag set cause segfaults when collected. to Singleton PMCs with the active_destroy flag set cause segfaults when collected

  Changed 3 years ago by jkeenan

Would it be possible to rework the patch such that it includes the Makefile changes which would be needed to test the patch and the sample code?

Thank you very much.


  Changed 3 years ago by cotto

  • status changed from new to closed
  • resolution set to fixed

I don't see this behavior any longer so I'm closing this ticket.

Note: See TracTickets for help on using tickets.