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

[perl #41642] [BUG] tailcall with slurpy gives segfault

1 view
Skip to first unread message

Mehmet Yavuz Selim Soyturk

unread,
Feb 28, 2007, 11:54:19 AM2/28/07
to bugs-bi...@rt.perl.org
# New Ticket Created by "Mehmet Yavuz Selim Soyturk"
# Please include the string: [perl #41642]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=41642 >


###################################
## file tail.pir:

.namespace [ 'Wrapper' ]

.sub call :method
.param pmc params :slurpy

.local pmc sub
sub = getattribute self, 'sub'

.local pmc a, b
a = params[0]
b = params[1]

# no problem here
# $P2 = sub(self, a, b)
# .return ($P2)

# tailcall 1
.return sub(self, a, b)
.end

.namespace

.sub add_tail # tail call
.param pmc wrapper
.param pmc a
.param pmc b

if b == 0 goto end
$P0 = new .Undef
$P0 = a + 1
$P1 = new .Undef
$P1 = b - 1

# no problem here
#$P2 = wrapper.call($P0, $P1)
#.return ($P2)

# tailcall 2
.return wrapper.call($P0, $P1)
end:
.return (a)
.end

.sub main :main
$P0 = newclass 'Wrapper'
addattribute $P0, 'sub'

.local pmc wrapper
wrapper = new 'Wrapper'
.const .Sub add = 'add_tail'
setattribute wrapper, 'sub', add


$P1 = new .Float
$P2 = new .Float
$P1 = 1
$P2 = 900

$P0 = wrapper.call($P1, $P2)
say $P0
.end

###########

That program causes me segfault. I only did get a segfault when:
1) there is a tailcall _method_
2) the method gets its parameters with :slurpy

I don't get any error if I invoke parrot with the -G flag.

Wrapper represent my hll function and wraps a pir sub.

#########
$ uname -a
Linux laptop 2.6.17-11-386 #2 Thu Feb 1 19:50:13 UTC 2007 i686 GNU/Linux

$ gcc --version
gcc (GCC) 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

some output for perl Contigure.pl:

Determining if your C compiler is actually gcc.........................yes.
Enabling optimization...................................................no.
Determining flags for building shared libraries......................-fPIC.
Determine if parrot should be linked against a shared library..........yes.
Determining your minimum pointer alignment......................... 1 byte.
Computing native byteorder for Parrot's wordsize.............little-endian.
Test the type of va_ptr (this test is likely to segfault)..............x86.
Determining if your C library has a working S_ISREG....................yes.
Verifying that the compiler supports function pointer casts............yes.
Determining whether your compiler supports computed goto...............yes.
Determining if your compiler supports inline...........................yes.
Determining if your C library supports memalign........................yes.
Determining Parrot's revision.......................................r17213.

Bob Rogers

unread,
Feb 28, 2007, 9:37:58 PM2/28/07
to perl6-i...@perl.org, bugs-bi...@rt.perl.org
From: "Mehmet Yavuz Selim Soyturk" (via RT) <parrotbug...@parrotcode.org>
Date: Wed, 28 Feb 2007 08:54:19 -0800

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

That program causes me segfault. I only did get a segfault when:


1) there is a tailcall _method_
2) the method gets its parameters with :slurpy

I don't get any error if I invoke parrot with the -G flag . . .

Does the following patch fix it? If so, and this patch does work for me
in r17222, then this is the same problem I discovered on 25-Dec-06:

From: Bob Rogers <rogers...@rgrjr.dyndns.org>
Subject: GC problem in parrot_pass_args to a tailcall (r16239)
Date: Mon, 25 Dec 2006 15:30:32 -0500

There is a repeatable segfault when GC is triggered during argument
passing after a tailcall. The immediate symptom is that clone_key_arg
blows cookies because the current arg is a 0xdeadbeef PMC. Apparently,
the sweep doesn't see pointers in the old context . . .

My test case didn't require a method, but I also couldn't reproduce it
reliably without a code tweak to force a GC during arg processing.

I still don't know what the "real" fix ought to look like. It wasn't
obvious to me at the time . . . and then I got too busy.

-- Bob Rogers
http://rgrjr.dyndns.org/

pass-args-block-dod-kludge.patch

Mehmet Yavuz Selim Soyturk

unread,
Mar 1, 2007, 7:17:34 AM3/1/07
to perl6-i...@perl.org
> Does the following patch fix it?

Sorry, I can't test if that patch helps. I was getting consistently a
segfault for that sort of tailcalls, but now it's gone. As far as I
can remember, I didn't change anything to parrot (no updates, the same
default configuration). I only did a reboot. I don't know if a reboot
can cause it though.

Mehmet Yavuz Selim Soyturk

unread,
Mar 1, 2007, 8:51:25 AM3/1/07
to perl6-i...@perl.org
I was able to reproduce that problem. Yesterday I was playing with
variations of the next program which causes a memory leak. I ran that
program again. I then ran the tail.pir, and it did segfault again.

And that patch solved that problem. I tested tail.pir 4 times
alternating with and without the patch.

=============
memleak.pir:
.sub main :main
loop:
$P0 = new .String
goto loop
.end

--
Mehmet


--
Mehmet

jnthn@jnthn.net via RT

unread,
Mar 2, 2007, 4:45:20 PM3/2/07
to perl6-i...@perl.org
Hi,

I just fixed a GC bug relating to slurpys (a more general one reported
by Bernhard++, not just specific to tail calls) in the args passing
code. Please check with the latest in SVN and see if that resolves the
problem.

(Bob, your patch was heading in the right direction, but I fixed this
without blocking DOD and more generally than just for tail calls. Thanks
though!)

Thanks,

Jonathan

Bob Rogers

unread,
Mar 2, 2007, 9:34:45 PM3/2/07
to parrotbug...@parrotcode.org, perl6-i...@perl.org
From: "jn...@jnthn.net via RT" <parrotbug...@parrotcode.org>
Date: Fri, 02 Mar 2007 13:45:20 -0800

Hi,

I just fixed a GC bug relating to slurpys (a more general one reported
by Bernhard++, not just specific to tail calls) in the args passing
code. Please check with the latest in SVN and see if that resolves the
problem.

Mehmet's original test case runs to completion in r17298, but I'm afraid
it still fails for me if the attached patch is applied, which forces DOD
every time parrot_pass_args is called. So I think this is a different
issue than the one you fixed.

(Bob, your patch was heading in the right direction, but I fixed this
without blocking DOD and more generally than just for tail calls. Thanks
though!)

Thanks. I know mine is just a band-aid, and a rather scruffy one at
that . . .

I hope I have time to investigate further this weekend. I am also
hoping the solution will also help with returning results after calling
actions, where the results come from a third context, and not the
returning (action) context. This is a project I got stuck on last fall.

-- Bob

arg-passing-force-gc.patch

Bob Rogers

unread,
Mar 3, 2007, 10:36:46 PM3/3/07
to parrotbug...@parrotcode.org
When the get_params instruction runs, the arguments are pulled from
the context pointed to by the caller_ctx member of the running context.
After a tailcall, the caller_ctx can be the only pointer left to the
caller's context. This member is not traced by mark_context, so a GC
before get_params has finished can reclaim arguments prematurely. The
obvious fix to mark_context (marking the caller_ctx) does indeed solve
the original problem, but introduces a host of other problems in "make
test" that seem to be GC-related, such as segfaults and nontermination.

To my surprise, I discovered that the ref_count of the caller_ctx was
already zero, even at the start of the tailcall instruction. This
probably means we're leaking contexts like crazy. It occurs to me that
if this context refcounting stuff really worked, we wouldn't even need
SUB_FLAG_TAILCALL, because the caller's context would get freed sooner
purely because it was not referenced by the return continuation.

So I'm going to think on this for a bit. Suggestions gratefully
accepted.

-- Bob

Will Coleda via RT

unread,
Dec 1, 2007, 10:15:00 PM12/1/07
to perl6-i...@perl.org

This bug seems to be gone in r23321; I had to update the example a bit
(have to use wrapper.'call' now instead of just wrapper.call) (attached
in RT) ; I ran it through the gcdebug runcore to expose any GC bugs, and
it printed 901, which seems to be the proper behavior.

Any followup issues please open a fresh ticket.

Closing ticket.

41642.pir
0 new messages