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

[perl #22854] Incongruity in Parrot IO and/or Parrot I/O crashes on STDIN read

10 views
Skip to first unread message

Clinton A. Pierce

unread,
Jun 29, 2003, 5:58:04 PM6/29/03
to bugs-bi...@rt.perl.org
# New Ticket Created by "Clinton A. Pierce"
# Please include the string: [perl #22854]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=22854 >


This is either an oversight in the current implementation *or* its a bug. Or both. Bug described is on Win32.

To read a line of input:

readline Sx, Ix
Switches to line buffered mode and reads from fd Ix.

This works great:

readline $S0, 0
print $S0

But is the old, deprecated way of doing things. As a matter of fact, it's nigh impossible now to open an FD to a file and do anything useful with it as enough bits of the "old way" of doing things are dismantled now...


So, I'm trying to use the new ParrotIO stuff, and according to it I should get a ParrotIO object for STDIN:

fdopen $P1, 0, "r"

And then use the read Sx, Px, Ix function (which on a line-buffered descriptor line STDIN, should stop at EOL):

read $S0, $P1, 255

This crashes:

.sub _main
fdopen $P1, 0, "r" # STDIN
read $S0, $P1, 255
print $S0
end
.end

Suggestions welcome!

Leopold Toetsch

unread,
Jun 30, 2003, 3:40:18 AM6/30/03
to perl6-i...@perl.org, bugs-bi...@netlabs.develooper.com
Clinton A. Pierce (via RT) wrote:

> Suggestions welcome!

First, always check the result of IO operations. If something fails,
these return a PerlUndef, so:


.sub _main
fdopen $P1, 0, "r" # STDIN

defined $I0, $P1
unless $I0, err


read $S0, $P1, 255
print $S0
end

err:
print "fdopen failed\n"
end
.end

2. C<fdopen> was disabled totally due to a wrong #ifdef
3. its currently only defined for PIO_OS_UNIX
4. Thanks again for your really valuable bug reports.

leo

Clinton Pierce

unread,
Jun 30, 2003, 8:26:18 AM6/30/03
to Leopold Toetsch, perl6-i...@perl.org, bugs-bi...@netlabs.develooper.com
> First, always check the result of IO operations. If something fails,
> these return a PerlUndef, so:
> .sub _main
> fdopen $P1, 0, "r" # STDIN
> defined $I0, $P1

*Doh* Stupid Newbie Error.

> unless $I0, err
> read $S0, $P1, 255
> print $S0
> end
> err:
> print "fdopen failed\n"
> end
> .end
>
> 2. C<fdopen> was disabled totally due to a wrong #ifdef
> 3. its currently only defined for PIO_OS_UNIX

Okaaay, so the plan is for this to work and I should probably code this way anyway, right?

Leopold Toetsch

unread,
Jun 30, 2003, 9:45:24 AM6/30/03
to Clinton Pierce, perl6-i...@perl.org
Clinton Pierce <cli...@geeksalad.org> wrote:
>> .sub _main
>> fdopen $P1, 0, "r" # STDIN

BTW
fdopen $P1, 0, "<" # read STDIN

>> 3. its currently only defined for PIO_OS_UNIX

> Okaaay, so the plan is for this to work and I should probably code this way anyway, right?

You could just delete the #ifdef PIO_OS_UNIX in io.ops:fdopen and see,
if its working.

leo

Clinton Pierce

unread,
Jul 8, 2003, 11:17:07 AM7/8/03
to perl6-i...@perl.org, Leopold Toetsch
>>> .sub _main
>>> fdopen $P1, 0, "r" # STDIN
>
>BTW
> fdopen $P1, 0, "<" # read STDIN
>
>>> 3. its currently only defined for PIO_OS_UNIX
>
>> Okaaay, so the plan is for this to work and I should probably code this way anyway, right?
>
> You could just delete the #ifdef PIO_OS_UNIX in io.ops:fdopen and see,
> if its working.

Given Jürgen's patch to completely remove the integer file descriptors and to add the getstdin, getstdout, and getstderr I think this bug can be dropped. fdopen() isn't completely functional under Win32 (either that, or I blew the part where I expose the Unix interface) but this should take care of most fd problems in Win32. (I don't think I've *ever* seen a Windows program pass a file descriptor...)

Given that, there's a possible bug in Jürgen's patch (or IMCC?). Given:

.sub _main
call _INIT
.arg 0
call _READLINE
.result $S0
print $S0
end
.end
.sub _INIT
$P0=new PerlArray # Array of BASIC FD's
getstdin $P1 # traditional #0


defined $I0, $P1
unless $I0, err

$P0[0]=$P1
getstdout $P1 # traditional #1, etc...
$P0[1]=$P1


defined $I0, $P1
unless $I0, err

store_global "FDS", $P0
ret
err: print "Cannot get handle for STDIN"
end
.end
.sub _READLINE # string readline(int fd)
saveall
.param int fd
find_global $P0, "FDS"
$P1=$P0[fd]
set $S0, ""
read $S0, $P1, 255 # <-- Crunch
.return $S0
restoreall
ret
.end

This produces the PASM:

_main:
bsr _INIT
save 0
bsr _READLINE
restore S0
print S0
end
_INIT:
new P1, 19 # .PerlArray
getstdin P0
defined I0, P0
unless I0, err
set P1[0], P0
getstdout P0 # <-- bug is here? Overwrote my P0.
set P1[1], P0
store_global "FDS", P1
ret
err:
print "Cannot get handle for STDIN"
end
_READLINE:
saveall
restore I0
find_global P0, "FDS"
set P0, P0[I0]
set S0, ""
read S0, P0, 255
save S0
restoreall
ret

Given that I'm just taking STDIN, STDOUT, STDERR and trying to stuff them into an array, should I have to use three different registers for this in the PIR?

new $P4, PerlArray
getstdin $P0
getstdout $P1
getstderr $P2
$P4[0], $P0
$P4[1], $P1
$P4[2], $P2

Or should getstdin/out/err have not overwritten the Px register and given up a new one each time?

Either behavior is fine, so long as we're consistant and/or documented.

Leopold Toetsch

unread,
Jul 8, 2003, 12:17:39 PM7/8/03
to Clinton Pierce, perl6-i...@perl.org
Clinton Pierce wrote:

> set P1[0], P0
> getstdout P0 # <-- bug is here? Overwrote my P0.
> set P1[1], P0


Yep a bug is here. But this bug is a BASIC compiler bug. Things that go
into aggregates (or are stored in lex pads/global tables) are stored by
reference. You have to clone PMCs to get independed vars:

.sub _main
$P0 = new PerlArray
$P1 = new PerlString
$P1 = "ok\n"
$P0[0] = $P1
$P1 = "no\n"
$P0[1] = $P1
$P2 = $P0[0]
$P3 = $P0[1]
print $P2
print $P3
end
.end

$ parrot pierce.imc
no
no


leo


Leopold Toetsch

unread,
Jul 8, 2003, 12:25:44 PM7/8/03
to Clinton Pierce, perl6-i...@perl.org, Leopold Toetsch
Clinton Pierce wrote:

> new $P4, PerlArray

A current workaround for the missing clone in ParrotIO:


getstdin P0
getstdout P1
getstderr P2
$P4[0], P0
$P4[1], P1
$P4[2], P2


leo


Juergen Boemmels

unread,
Jul 8, 2003, 2:09:32 PM7/8/03
to Clinton Pierce, Perl6 Internals
"Clinton Pierce" <cli...@geeksalad.org> writes:

What is that supposed to do?
As I understand it it reads a line from stdin and writes it to
standard out.

A short test of this code simply worked.

If it does not work for you, can you send me a parrot -t of this code?

> This produces the PASM:
>
> _main:
> bsr _INIT
> save 0
> bsr _READLINE
> restore S0
> print S0
> end
> _INIT:
> new P1, 19 # .PerlArray
> getstdin P0
> defined I0, P0
> unless I0, err
> set P1[0], P0
> getstdout P0 # <-- bug is here? Overwrote my P0.

Overwriting P0 is not a problem here. You don't use it any more.
Overwriting P1[0] would be a problem, but this should not be the case
because getstd* create always a new PMC.

> set P1[1], P0
> store_global "FDS", P1
> ret
> err:
> print "Cannot get handle for STDIN"
> end
> _READLINE:
> saveall
> restore I0
> find_global P0, "FDS"
> set P0, P0[I0]
> set S0, ""
> read S0, P0, 255
> save S0
> restoreall
> ret

> Either behavior is fine, so long as we're consistant and/or documented.

getstd* Px don't change the value of the old Px, but changing the
pointer to a new PMC. Its like
set P0, P1
and not like
assign P0, P1

bye
boe
--
Juergen Boemmels boem...@physik.uni-kl.de
Fachbereich Physik Tel: ++49-(0)631-205-2817
Universitaet Kaiserslautern Fax: ++49-(0)631-205-3906
PGP Key fingerprint = 9F 56 54 3D 45 C1 32 6F 23 F6 C7 2F 85 93 DD 47

Clinton Pierce

unread,
Jul 8, 2003, 3:09:22 PM7/8/03
to Juergen Boemmels, Perl6 Internals
I'm not sure whether getstd\w+ is supposed to give me a new reference or not. From now on I'll code that portion defensively.

What I do know is that imcc -t under Win32 is crash-happy and I can't trace beyond the first getstdin. Greatly simplified example:

.sub _main
$P0=new PerlArray
getstdin P2
defined $I0, P2
unless $I0, err
$P0[0]=P2
getstderr P3 # STDOUT
defined $I0, P3 # STDOUT
$P0[1]=P3 # STDOUT
unless $I0, err # STDOUT

$P1=$P0[0]


set $S0, ""
read $S0, $P1, 255

print $S0
end

err:print "Error"
end
.end

The above code crashes, but not where I thought it did -- it occurs immediately *after* the read in either the print or end. Do any one of the following and the code works great:

* Remove the print $S0 -- things are fine
* Remove the code indicated by # STDOUT -- things are fine
* Remove the read $S0, $P1, 255 -- peachy as well.


[Offtopic: a small plea goes out to anyone who can get imcc -t under Win32 to not crash...]

Clinton Pierce

unread,
Jul 8, 2003, 3:13:53 PM7/8/03
to Juergen Boemmels, Perl6 Internals
Typo!

> getstderr P3 # STDOUT
^^^^

Should have been "getstdout"

Although... if left at getstderr the error also goes away. (Add that to my bullet list.) My haven't-grokked-the-code psychic abilities tell me that "getstdout" does something Real Bad to the stdout filehandle and any later uses of it (with print?) cause segfaults.


Leopold Toetsch

unread,
Jul 8, 2003, 5:00:56 PM7/8/03
to Clinton Pierce, Juergen Boemmels, Perl6 Internals
Clinton Pierce wrote:

> What I do know is that imcc -t under Win32 is crash-happy

Snippet runs fine on Linux (with typo adjusted or not) as well as your
previous one, -t or not.
But, as IO is under *construction* some issues might remain. They'll get
resolved.

leo

0 new messages