Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[perl #40966] [BUG] Parrot core dumps in perl6 (possible GC/pointer bug?)

3 views
Skip to first unread message

Patrick R . Michaud

unread,
Nov 22, 2006, 11:43:24 AM11/22/06
to bugs-bi...@rt.perl.org
# New Ticket Created by Patrick R. Michaud
# Please include the string: [perl #40966]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=40966 >


---
osname= linux
osvers= 2.6.16
arch= x86_64-linux-thread-multi
cc= cc
---
Flags:
category=core
severity=high
ack=no
---
With the latest changes to the perl6 compiler I'm starting to see
miscellaneous core dumps from Parrot. I think it's likely GC or
pointer related, as the program in question runs correctly with the
-G flag present.

The core dump appears for me in r15764. The steps to build perl6.pbc:

1. build parrot
2. cd languages/perl6
3. make

After building the perl6.pbc compiler, running perl6.pbc on
t/00-parrot/07-op-string.t produces the core dump:

$ ../../parrot perl6.pbc t/00-parrot/07-op-string.t
parrot: src/string.c:2086: string_hash: Assertion `s->encoding && s->charset && !(((s)->obj.flags) & b_PObj_on_free_list_FLAG)' failed.
Aborted (core dumped)

Running with the -G flag produces the correct output:

$ ../../parrot -G perl6.pbc t/00-parrot/07-op-string.t
1..16
ok 1
ok 2
ok 3
ok 4
ok 5
ok 6
ok 7
ok 8
ok 9
ok 10
ok 11
ok 12
ok 13
ok 14
ok 15
ok 16

The backtrace (complete copy below) shows the execution stack
at the time of the core dump:

#0 0x00002ba87019baa5 in raise () from /lib64/libc.so.6
#1 0x00002ba87019ce60 in abort () from /lib64/libc.so.6
#2 0x00002ba870195246 in __assert_fail () from /lib64/libc.so.6
#3 0x00002ba86f2c8220 in string_hash (interp=0x50c010, s=0x792a00, seed=3793)
at src/string.c:2086
#4 0x00002ba86f2d0718 in key_hash_STRING (interp=0x50c010, value=0x792a00,
seed=3793) at src/hash.c:62
#5 0x00002ba86f2d165e in parrot_hash_get_bucket (interp=0x50c010,
hash=0xa0ebc0, key=0x792a00) at src/hash.c:788
#6 0x00002ba86f376a52 in Parrot_Hash_exists_keyed (interp=0x50c010,
pmc=0x2aaaaae21590, key=0x0) at src/pmc/hash.pmc:858
#7 0x00002ba86f1fb64a in Parrot_exists_i_p_kc (cur_opcode=0x2aaaaac8a3d0,
interp=0x50c010) at src/ops/pmc.ops:318
#8 0x00002ba86f2cb061 in runops_slow_core (interp=0x50c010, pc=0x2aaaaac8a3d0)
at src/runops_cores.c:184
#9 0x00002ba86f2b317a in runops_int (interp=0x50c010, offset=137)
at src/interpreter.c:775
#10 0x00002ba86f2b8a3e in runops (interp=0x50c010, offs=137)
at src/inter_run.c:87
#11 0x00002ba86f2b8cd8 in runops_args (interp=0x50c010, sub=0x7e6c58,
obj=0x550350, meth=0x0, sig=0x2ba86f3e8212 "vP", ap=0x7fff3bb20470)
at src/inter_run.c:193
#12 0x00002ba86f2b8ecb in Parrot_runops_fromc_args (interp=0x50c010,
sub=0x7e6c58, sig=0x2ba86f3e8212 "vP") at src/inter_run.c:295
#13 0x00002ba86f2d9208 in Parrot_runcode (interp=0x50c010, argc=2,
argv=0x7fff3bb20790) at src/embed.c:806
#14 0x00000000004035a6 in main (argc=2, argv=0x7fff3bb20790)
at compilers/imcc/main.c:723

Thanks!

Pm

====complete transcript including backtrace====

$ ../../parrot perl6.pbc t/00-parrot/07-op-string.t
parrot: src/string.c:2086: string_hash: Assertion `s->encoding && s->charset && !(((s)->obj.flags) & b_PObj_on_free_list_FLAG)' failed.
Aborted (core dumped)
$ ../../parrot -G perl6.pbc t/00-parrot/07-op-string.t
1..16
ok 1
ok 2
ok 3
ok 4
ok 5
ok 6
ok 7
ok 8
ok 9
ok 10
ok 11
ok 12
ok 13
ok 14
ok 15
ok 16
$ gdb ../../parrot core.26512
GNU gdb 6.4
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-suse-linux"...Using host libthread_db library "/lib64/libthread_db.so.1".

Core was generated by `../../parrot perl6.pbc t/00-parrot/07-op-string.t'.
Program terminated with signal 6, Aborted.
Reading symbols from /home/pmichaud/parrot/trunk/blib/lib/libparrot.so.0.4.7...done.
Loaded symbols for /home/pmichaud/parrot/trunk/blib/lib/libparrot.so.0.4.7
Reading symbols from /lib64/libdl.so.2...done.
Loaded symbols for /lib64/libdl.so.2
Reading symbols from /lib64/libcrypt.so.1...done.
Loaded symbols for /lib64/libcrypt.so.1
Reading symbols from /lib64/libpthread.so.0...done.
Loaded symbols for /lib64/libpthread.so.0
Reading symbols from /lib64/librt.so.1...done.
Loaded symbols for /lib64/librt.so.1
Reading symbols from /lib64/libreadline.so.5...done.
Loaded symbols for /lib64/libreadline.so.5
Reading symbols from /lib64/libncurses.so.5...done.
Loaded symbols for /lib64/libncurses.so.5
Reading symbols from /usr/lib64/libstdc++.so.6...done.
Loaded symbols for /usr/lib64/libstdc++.so.6
Reading symbols from /lib64/libm.so.6...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /lib64/libgcc_s.so.1...done.
Loaded symbols for /lib64/libgcc_s.so.1
Reading symbols from /lib64/libc.so.6...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from /home/pmichaud/parrot/trunk/runtime/parrot/dynext/perl6_group.so...done.
Loaded symbols for /home/pmichaud/parrot/trunk/runtime/parrot/dynext/perl6_group.so
#0 0x00002ba87019baa5 in raise () from /lib64/libc.so.6
(gdb) bt
#0 0x00002ba87019baa5 in raise () from /lib64/libc.so.6
#1 0x00002ba87019ce60 in abort () from /lib64/libc.so.6
#2 0x00002ba870195246 in __assert_fail () from /lib64/libc.so.6
#3 0x00002ba86f2c8220 in string_hash (interp=0x50c010, s=0x792a00, seed=3793)
at src/string.c:2086
#4 0x00002ba86f2d0718 in key_hash_STRING (interp=0x50c010, value=0x792a00,
seed=3793) at src/hash.c:62
#5 0x00002ba86f2d165e in parrot_hash_get_bucket (interp=0x50c010,
hash=0xa0ebc0, key=0x792a00) at src/hash.c:788
#6 0x00002ba86f376a52 in Parrot_Hash_exists_keyed (interp=0x50c010,
pmc=0x2aaaaae21590, key=0x0) at src/pmc/hash.pmc:858
#7 0x00002ba86f1fb64a in Parrot_exists_i_p_kc (cur_opcode=0x2aaaaac8a3d0,
interp=0x50c010) at src/ops/pmc.ops:318
#8 0x00002ba86f2cb061 in runops_slow_core (interp=0x50c010, pc=0x2aaaaac8a3d0)
at src/runops_cores.c:184
#9 0x00002ba86f2b317a in runops_int (interp=0x50c010, offset=137)
at src/interpreter.c:775
#10 0x00002ba86f2b8a3e in runops (interp=0x50c010, offs=137)
at src/inter_run.c:87
#11 0x00002ba86f2b8cd8 in runops_args (interp=0x50c010, sub=0x7e6c58,
obj=0x550350, meth=0x0, sig=0x2ba86f3e8212 "vP", ap=0x7fff3bb20470)
at src/inter_run.c:193
#12 0x00002ba86f2b8ecb in Parrot_runops_fromc_args (interp=0x50c010,
sub=0x7e6c58, sig=0x2ba86f3e8212 "vP") at src/inter_run.c:295
#13 0x00002ba86f2d9208 in Parrot_runcode (interp=0x50c010, argc=2,
argv=0x7fff3bb20790) at src/embed.c:806
#14 0x00000000004035a6 in main (argc=2, argv=0x7fff3bb20790)
at compilers/imcc/main.c:723
(gdb)


---
Summary of my parrot 0.4.7 (r15763) configuration:
configdate='Wed Nov 22 10:32:12 2006'
Platform:
osname=linux, archname=x86_64-linux-thread-multi
jitcapable=0, jitarchname=nojit,
jitosname=linux, jitcpuarch=x86_64
execcapable=0
perl=/usr/bin/perl
Compiler:
cc='ccache gcc', ccflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING -pipe -Wdeclaration-after-statement -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC',
Linker and Libraries:
ld='ccache g++', ldflags=' -L/usr/local/lib64',
cc_ldflags='',
libs='-lm -ldl -lcrypt -lpthread -lrt -lreadline -lncurses'
Dynamic Linking:
share_ext='.so', ld_share_flags='-shared -L/usr/local/lib64 -fPIC',
load_ext='.so', ld_load_flags='-shared -L/usr/local/lib64 -fPIC'
Types:
iv=long, intvalsize=8, intsize=4, opcode_t=long, opcode_t_size=8,
ptrsize=8, ptr_alignment=1 byteorder=12345678,
nv=double, numvalsize=8, doublesize=8

---
Environment:
HOME LANG LANGUAGE LD_LIBRARY_PATH LOGDIR PATH SHELL

Matt Diephouse

unread,
Dec 5, 2006, 2:39:28 PM12/5/06
to p6i, bugs-bi...@rt.perl.org
via RT Patrick R. Michaud <parrotbug...@parrotcode.org> wrote:
> With the latest changes to the perl6 compiler I'm starting to see
> miscellaneous core dumps from Parrot. I think it's likely GC or
> pointer related, as the program in question runs correctly with the
> -G flag present.
>
> The core dump appears for me in r15764. The steps to build perl6.pbc:
>
> 1. build parrot
> 2. cd languages/perl6
> 3. make
>
> After building the perl6.pbc compiler, running perl6.pbc on
> t/00-parrot/07-op-string.t produces the core dump:
>
> $ ../../parrot perl6.pbc t/00-parrot/07-op-string.t
> parrot: src/string.c:2086: string_hash: Assertion `s->encoding && s->charset && !(((s)->obj.flags) & b_PObj_on_free_list_FLAG)' failed.
> Aborted (core dumped)

While I didn't get this error here, I got it on one of the other Perl6
tests and spent some time debugging. The portion of the assertion that
fails is

!(((s)->obj.flags) & b_PObj_on_free_list_FLAG

which means that this string has been garbage collected. I saw a
couple different instances of this problem and in all of them, the
string in question was a constant (some were C-level and others were
PIR-level).

So the underlying problem is that constant strings are getting
collected when they shouldn't. The easy fix is to not collect *any*
constant PObj headers (see patch below). Is this correct? Or is there
a case when they should get collected? If it's the later, does somehow
know how to fix the issue?

--
Matt Diephouse
http://matt.diephouse.com

Index: src/dod.c
===================================================================
--- src/dod.c (revision 15920)
+++ src/dod.c (working copy)
@@ -553,6 +553,8 @@
for (i = nm = 0; i < cur_arena->used; i++) {
if (PObj_on_free_list_TEST(b))
; /* if its on free list, do nothing */
+ else if (PObj_constant_TEST(b))
+ ; /* if its a constant, do nothing */
else if (PObj_live_TEST(b)) {
/* its live */
total_used++;

Leopold Toetsch

unread,
Dec 5, 2006, 3:22:50 PM12/5/06
to perl6-i...@perl.org, ma...@diephouse.com, bugs-bi...@rt.perl.org
Am Dienstag, 5. Dezember 2006 20:39 schrieb Matt Diephouse:
> The portion of the assertion that
> fails is
>
>     !(((s)->obj.flags) & b_PObj_on_free_list_FLAG
>
> which means that this string has been garbage collected. I saw a
> couple different instances of this problem and in all of them, the
> string in question was a constant (some were C-level and others were
> PIR-level).
>
> So the underlying problem is that constant strings are getting
> collected when they shouldn't.

constants reside, when correctly created, in different object pools than
GC-able items (constant_pmc_pool, constant_string_header_pool). PMCs in the
constant_pmc_pool are marked during GC. No constant pool item is swept during
GC, i.e the are only collect on interpreter shutdown.

If above assert triggers, then some item are created in the wrong pool and
then stored as constants.

To track that further down, it'll be helpful to have some information about
the origin & contents of the GC-ed constant, but typically such creation code
is in imcc or packfile.

leo

Matt Diephouse

unread,
Dec 5, 2006, 4:07:13 PM12/5/06
to Leopold Toetsch, perl6-i...@perl.org, bugs-bi...@rt.perl.org
Leopold Toetsch <l...@toetsch.at> wrote:
> Am Dienstag, 5. Dezember 2006 20:39 schrieb Matt Diephouse:
> > The portion of the assertion that
> > fails is
> >
> > !(((s)->obj.flags) & b_PObj_on_free_list_FLAG
> >
> > which means that this string has been garbage collected. I saw a
> > couple different instances of this problem and in all of them, the
> > string in question was a constant (some were C-level and others were
> > PIR-level).
> >
> > So the underlying problem is that constant strings are getting
> > collected when they shouldn't.
>
> constants reside, when correctly created, in different object pools than
> GC-able items (constant_pmc_pool, constant_string_header_pool). PMCs in the
> constant_pmc_pool are marked during GC. No constant pool item is swept during
> GC, i.e the are only collect on interpreter shutdown.

Constant PMCs are marked, but are constant STRINGs?

> If above assert triggers, then some item are created in the wrong pool and
> then stored as constants.
>
> To track that further down, it'll be helpful to have some information about
> the origin & contents of the GC-ed constant, but typically such creation code
> is in imcc or packfile.

I'm on my laptop atm and it's not exhibiting the error, but the
constant in question was in a method call:

$P0.'method'('string constant that was getting collected', ...)

Leopold Toetsch

unread,
Dec 6, 2006, 2:46:23 PM12/6/06
to perl6-i...@perl.org, ma...@diephouse.com, bugs-bi...@rt.perl.org
Am Dienstag, 5. Dezember 2006 22:07 schrieb Matt Diephouse:
> Constant PMCs are marked, but are constant STRINGs?

As STRINGs aren't pointing to other items, there's no extra code to deal with
constant strings. They are marked, when refered to from other locations or
maybe not. This is ok, as the constant string pool isn't swept.

> > If above assert triggers, then some item are created in the wrong pool
> > and then stored as constants.
> >
> > To track that further down, it'll be helpful to have some information
> > about the origin & contents of the GC-ed constant, but typically such
> > creation code is in imcc or packfile.
>
> I'm on my laptop atm and it's not exhibiting the error, but the
> constant in question was in a method call:
>
>     $P0.'method'('string constant that was getting collected', ...)

The relevant code dealing with such constants is in pbc.c:add_const_str() or
more specifically in IMCC_string_from_reg(), which is creating STRINGs with
PObj_constant_FLAG set in all code paths AFAICS.

You could place an assert into the former function to verify that this flag is
set.

There must be some additional nastiness to trigger that GC bug.

leo

0 new messages