[Perl/perl5] 123127: SelfLoader: don't mix buffered and unbuffered I/O
[email protected] (Tony Cook via perl5-changes)
| Newsgroups | perl.perl5.changes |
|---|---|
| Message-ID | <Perl/perl5/push/refs/heads/smoke-me/tonyc/selfloader-mixed-io/[email protected]> |
Branch: refs/heads/smoke-me/tonyc/selfloader-mixed-io
Home: https://github.com/Perl/perl5
Commit: 12312765c57cf405efc9d96098f60dad006e3b5a
https://github.com/Perl/perl5/commit/12312765c57cf405efc9d96098f60dad006e3b5a
Author: Tony Cook <[email protected]>
Date: 2026-04-29 (Wed, 29 Apr 2026)
Changed paths:
M dist/SelfLoader/lib/SelfLoader.pm
Log Message:
-----------
SelfLoader: don't mix buffered and unbuffered I/O
For a long time SelfLoader has produced occasional smoke failures on
stdio runs, for example:
https://perl5.test-smoke.org/report/5530055
(aka https://perl.develop-help.com/db/5530055)
https://perl.develop-help.com/dblog/5530141
(aka https://perl.develop-help.com/db/5530141)
https://perl.develop-help.com/dblog/5529979
(aka https://perl.develop-help.com/db/5529979)
I've tried to track this down before, usually looking for interactions
between stdio and perlio in the perlio implementation.
When looking at it again, I saw the SelfLoader code was mixing
buffered I/O (tell()) and unbuffered I/O (sysseek()) which I could see
possibly leaving an unexpected difference in the seek position.
I suspect this *is* causing some bad interaction, if you look at the
strace before and after the change.
before:
write(1, "1..1\n", 5) = 5
lseek(3, 0, SEEK_CUR) = 808
lseek(3, 250, SEEK_SET) = 250
fcntl(3, F_DUPFD_CLOEXEC, 0) = 4
fcntl(4, F_GETFD) = 0x1 (flags FD_CLOEXEC)
fcntl(4, F_GETFL) = 0x8000 (flags O_RDONLY|O_LARGEFILE)
fcntl(4, F_SETFD, FD_CLOEXEC) = 0
fstat(4, {st_mode=S_IFREG|0644, st_size=808, ...}) = 0
lseek(3, 0, SEEK_CUR) = 250
close(3) = 0
close(4) = 0
write(1, "not ok 1 - syntax errors are rep"..., 38) = 38
after:
write(1, "1..1\n", 5) = 5
lseek(3, 0, SEEK_CUR) = 808
lseek(3, 0, SEEK_SET) = 0
read(3, "use SelfLoader;\nprint \"1..1\\n\";\n"..., 4096) = 808
fcntl(3, F_DUPFD_CLOEXEC, 0) = 4
fcntl(4, F_GETFD) = 0x1 (flags FD_CLOEXEC)
fcntl(4, F_GETFL) = 0x8000 (flags O_RDONLY|O_LARGEFILE)
fcntl(4, F_SETFD, FD_CLOEXEC) = 0
fstat(4, {st_mode=S_IFREG|0644, st_size=808, ...}) = 0
lseek(3, 250, SEEK_SET) = 250
close(3) = 0
fcntl(4, F_DUPFD_CLOEXEC, 0) = 3
fcntl(3, F_GETFL) = 0x8000 (flags O_RDONLY|O_LARGEFILE)
fcntl(3, F_SETFD, FD_CLOEXEC) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=808, ...}) = 0
close(4) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=808, ...}) = 0
read(3, "\nsub buggy\n{\n +>*;\n}\n\n\n# RT 4"..., 4096) = 558
read(3, "", 4096) = 0
write(1, "ok 1 - syntax errors are reporte"..., 34) = 34
we can see in the original the file offset is at end of file, and that
is copied into the cloned handles, so reads of the cloned
handles (which don't have the buffer of the original handle) read
nothing, and in the case of this particular
test (02SelfLoader-buggy.t) the erroneous code isn't read and no error
is reported.
It's unclear to me what the original change here was intended to fix,
the original change here landed in two steps, first add1a1a3c3d,
discussed in
https://www.nntp.perl.org/group/perl.perl5.porters/2006/12/msg119237.html
and then 054149a8968 discussed in the thread starting at
https://www.nntp.perl.org/group/perl.perl5.porters/2006/12/msg119449.html
Since we're dupping the handle each time (see the strace for the
success case) I'd expect the descriptor to share their file positions
between forked processes anyway.
Commit: 5522efcc59679168050e3f23b4c32c1c6261578b
https://github.com/Perl/perl5/commit/5522efcc59679168050e3f23b4c32c1c6261578b
Author: Tony Cook <[email protected]>
Date: 2026-04-29 (Wed, 29 Apr 2026)
Changed paths:
M dist/SelfLoader/lib/SelfLoader.pm
Log Message:
-----------
bump $SelfLoader::VERSION
Compare: https://github.com/Perl/perl5/compare/12312765c57c%5E...5522efcc5967
To unsubscribe from these emails, change your notification settings at https://github.com/Perl/perl5/settings/notifications