# New Ticket Created by  Mark Glines 
# Please include the string:  [perl #43102]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=43102 >


While testing/trying to fix RT #42938, I noticed an additional test
failure in t/pmc/threads.t.  Test 7 crashes with a signal 11
(segmentation fault), on my Gentoo Linux-x86 box.  This is with svn
r18722.

I've stared at gdb, header files and preprocessor output for a while.
I'll include all the info I think is relevant.


t/pmc/threads....NOK 7/20
#     Failed test (t/pmc/threads.t at line 290)
# Exited with error code: [SIGNAL 11]
# Received:
# thread
#
# Expected:
# /(done\nthread\n)|(thread\ndone\n)/
#

Starting program: /home/paranoid/parrot/parrot detach.pir
[Thread debugging using libthread_db enabled]
[New Thread -1227352400 (LWP 25907)]
warning: Lowest section in /usr/lib/libicudata.so.36 is .hash at 000000d4
[New Thread -1227355216 (LWP 25910)]
[New Thread -1235747920 (LWP 25911)]
[New Thread -1244140624 (LWP 25912)]
thread

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1244140624 (LWP 25912)]
0xb7da53ab in clear_cow (interp=0x82256f0, pool=0x82285c8, cleanup=1)
    at src/gc/dod.c:469
469                         *refcount               = 0;
(gdb) print refcount
$1 = (INTVAL * const) 0xb7eb4b41


The code in question:
                    INTVAL * const refcount = PObj_bufrefcountptr(b);
                    *refcount               = 0;

Which expands to:
                    INTVAL * const refcount = (&(((Buffer_alloc_unit *)((char 
*) (b)->obj.u._b._bufstart - (((size_t) &((Buffer_alloc_unit 
*)0)->buffer))))->ref_ count));
                    *refcount = 0;

(gdb) bt
#0  0xb7da53ab in clear_cow (interp=0x82256f0, pool=0x82285c8,
    cleanup=1) at src/gc/dod.c:469
#1  0xb7da30ae in sweep_cb_buf (interp=0x82256f0, pool=0x82285c8, flag=6,
    arg=0x0) at src/headers.c:691
#2  0xb7da2f56 in Parrot_forall_header_pools (interp=0x82256f0, flag=6,
    arg=0x0, func=0xb7da3080 <sweep_cb_buf>) at src/headers.c:640
#3  0xb7da318f in Parrot_destroy_header_pools (interp=0x82256f0)
    at src/headers.c:732
#4  0xb7d490bb in Parrot_really_destroy (interp=0x82256f0, exit_code=0,
    arg=0x0) at src/inter_create.c:390
#5  0xb7dc5399 in thread_func (arg=0x83c0c28) at src/thread.c:403
#6  0xb7b6f380 in start_thread () from /lib/libpthread.so.0
#7  0xb6f1554e in clone () from /lib/libc.so.6
(gdb) print *b
$3 = {obj = {u = {_b = {_bufstart = 0xb7eb4b45, _buflen = 6}, _ptrs = {
        _struct_val = 0xb7eb4b45, _pmc_val = 0x6}, _i = {
        _int_val = -1209316539, _int_val2 = 6},
      _num_val = 1.425648877988937e-313, _string_val = 0xb7eb4b45},
    flags = 196864}}
(gdb) print ((char*)(b->obj.u._b._bufstart))
$4 = 0xb7eb4b45 "parrot"


So it looks to me like it's expecting to find a refcount integer right
before the buffer, in memory.  But the buffer is a null-terminated
string, packed in memory with another string directly preceding it...
no refcount integer!

Here's a hexdump of the memory:

b7eb4b30  75 70 2e 63 00 28 73 65  6c 66 29 2d 3e 70 6d 63  |up.c~(self)->pmc|
b7eb4b40  5f 65 78 74 00 70 61 72  72 6f 74 00 00 00 00 00  |_ext~parrot~~~~~|
_bufstart pointer:       ^^                                       ^

(in the ASCII part of that hexdump, "~" means null.)

I'm in way over my head here, but I see 3 warning signs telling me
this is a bug:

1.  The SIGSEGV, obviously.
2.  The lack of refcount integer where the code expects to find one.
3.  The buffer isn't dword-aligned.  (Aren't allocated buffers aligned
by default?  Could this be a constant string defined at compile time,
instead?)


I also get an intermittant failure of test 5 (occurs about once every 5
runs).  I believe it is likely to be caused by the same issue, but I
have not debugged it to the same extent.

#     Failed test (t/pmc/threads.t at line 204)
# Exited with error code: [SIGNAL 11]
# Received:
# start 1
# in thread
# done
#
# Expected:
# start 1
# in thread
# done

 
Mark

Reply via email to