#1780: Using StringHandle for STDERR can cause segfaults
-------------------------+--------------------------------------------------
 Reporter:  whiteknight  |       Owner:       
     Type:  bug          |      Status:  new  
 Priority:  normal       |   Milestone:       
Component:  none         |     Version:  2.7.0
 Severity:  medium       |    Keywords:       
     Lang:               |       Patch:       
 Platform:               |  
-------------------------+--------------------------------------------------
 Here's a simple test case that demonstrates the problem:
 {{{
 .include 'stdio.pasm'

 .sub main
     $P0 = getinterp
     $P1 = new ['StringHandle']
     $P1.'open'('blah', 'rw')
     $P0.'stdhandle'(.PIO_STDERR_FILENO, $P1)
     die "whatever"
 .end
 }}}

 What I do is map the standard error filehandle to a StringHandle object.
 Normally this part of the operation works just fine, and I am able to
 write error messages and extract them from the StringHandle. The problem
 comes when we have an unhandled exception. Here's a stack trace showing
 two iterations of what becomes an infinite loop:

 {{{
 Breakpoint 2, die_from_exception (interp=0x8052040, exception=0x80b4c68)
 at exceptions.c:96
 96          ASSERT_ARGS(die_from_exception)
 (gdb) bt
 #0  die_from_exception (interp=0x8052040, exception=0x80b4c68) at
 exceptions.c:96
 #1  0x001af64c in Parrot_ex_throw_from_c (interp=0x8052040,
 exception=0x80b4c68)
     at exceptions.c:350
 #2  0x001afb78 in Parrot_ex_throw_from_c_args (interp=0x8052040,
 ret_addr_unused=0x0,
     exitcode=27, format=0x36f230 "Cannot write to a closed filehandle") at
 exceptions.c:448
 #3  0x00317815 in Parrot_StringHandle_nci_puts (interp=0x8052040,
 _self=0x1d446d)
     at stringhandle.c:373
 #4  0x002d9f81 in Parrot_NativePCCMethod_invoke (interp=0x8052040,
 _self=0x80b2508, next=0x0)
     at nativepccmethod.c:117
 #5  0x001c9f4f in Parrot_pcc_invoke_from_sig_object (interp=0x8052040,
 sub_obj=0x80b2508,
     call_object=0x80b4c08) at pcc.c:317
 #6  0x001ca23a in Parrot_pcc_invoke_method_from_c_args (interp=0x8052040,
 pmc=0x80b4ba8,
     method_name=0x8073550, signature=0x36e63a "S->I") at pcc.c:208
 #7  0x00233f13 in Parrot_io_putps (interp=0x8052040, pmc=0x80b4ba8,
 s=0x80c3768) at api.c:624
 #8  0x0023488c in Parrot_io_eprintf (interp=0x8052040, s=0x364699 "%S\n")
 at api.c:719
 #9  0x001aeef0 in die_from_exception (interp=0x8052040,
 exception=0x80b4bf8) at exceptions.c:122
 #10 0x001af3d2 in Parrot_ex_throw_from_op (interp=0x8052040,
 exception=0x80b4bf8,
     dest=0x80fe1bc) at exceptions.c:236
 #11 0x001611d8 in Parrot_die_sc (cur_opcode=0x80fe1b4, interp=0x8052040)
 at core_ops.c:15796
 #12 0x0021bdf2 in runops_slow_core (interp=0x8052040,
 runcore_unused=0x80f1350, pc=0x80fe1b4)
     at cores.c:647
 #13 0x0021b1e8 in runops_int (interp=0x8052040, offset=0) at main.c:224
 #14 0x001d17d4 in runops (interp=0x8052040, offs=0) at ops.c:127
 #15 0x001c9fae in Parrot_pcc_invoke_from_sig_object (interp=0x8052040,
 sub_obj=0x80b4558,
     call_object=0x80b4618) at pcc.c:325
 #16 0x001b0e67 in Parrot_ext_call (interp=0x8052040, sub_pmc=0x80b4558,
     signature=0x36e12e "P->") at extend.c:322
 #17 0x001aca7b in Parrot_runcode (interp=0x8052040, argc=1,
 argv=0xbffff318) at embed.c:811
 ---Type <return> to continue, or q <return> to quit---
 #18 0x003364e3 in imcc_run_pbc (interp=0x8052040, output_file=0x0, argc=1,
 argv=0xbffff318)
     at main.c:415
 #19 0x08048fe8 in main (argc=2, argv=0xbffff314) at main.c:149
 }}}

 die_from_exception attempts to write the message "Cannot write to a closed
 filehandle" to the closed filehandle, which throws the same exception,
 which calls die_from_exception, which...

 This puts us into a really nasty infinite loop that always ends in
 segfault.

 Possible solutions:
 1) If we throw an exception while in die_from_exception, we should just
 close Parrot and not try to handle the new exception
 2) Be better about detecting when we can and cannot write to the
 StringHandle, and don't try to write to it if we're in a state that will
 cause a problem
 3) Figure out why the StringHandle, which I did open (and did not close)
 is throwing an exception about not being open for writing the final error
 message.
 4) If we're in a die_from_exception, or similar final situation, always
 write to STDERR, not a PMC type.

 We're probably going to want to do some or all of these things eventually.

-- 
Ticket URL: <https://trac.parrot.org/parrot/ticket/1780>
Parrot <https://trac.parrot.org/parrot/>
Parrot Development
_______________________________________________
parrot-tickets mailing list
[email protected]
http://lists.parrot.org/mailman/listinfo/parrot-tickets

Reply via email to