Subject: | errno problem (with PATCH) |
When using NYTProf in a big mod_perl application, the first
LWP::UserAgent request always fails. I failed to create a small test
script to reproduce the problem, so I will just describe the problem
with some strace logs.
I suspect the problem happens in connect() in IO::Socket:
if (!connect($sock, $addr)) {
if (defined $timeout && $!{EINPROGRESS}) {
require IO::Select;
If the problem occurs, then the connect() syscall returns EINPROGRESS
and thus the perl interpreter should go into the branch using "require
IO::Select". This really happens when running without NYTProf. Here the
strace log snippet (IO::Select is probably preloaded here, so one only
sees the select()):
23227 16:05:20.036746 connect(5, {sa_family=AF_INET, sin_port=htons(84),
sin_addr=inet_addr("172.17.30.1")}, 16) = -1 EINPROGRESS (Operation now
in progress)
23227 16:05:20.037018 select(8, NULL, [5], NULL, {10, 0}) = 1 (out [5],
left {10, 0})
23227 16:05:20.037259 connect(5, {sa_family=AF_INET, sin_port=htons(84),
sin_addr=inet_addr("172.17.30.1")}, 16) = 0
23227 16:05:20.037318 fcntl64(5, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
23227 16:05:20.037356 fcntl64(5, F_SETFL, O_RDWR) = 0
With NYTProf turned on, the strace log looks like following:
22647 15:43:17.078375 connect(5, {sa_family=AF_INET, sin_port=htons(84),
sin_addr=inet_addr("172.17.30.1")}, 16) = -1 EINPROGRESS (Operation now
in progress)
22647 15:43:17.078593 lstat64("/usr/lib/perl/5.8/Errno.pmc", 0xbfddf8dc)
= -1 ENOENT (No such file or directory)
22647 15:43:17.079400 fcntl64(5, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
22647 15:43:17.079462 fcntl64(5, F_SETFL, O_RDWR) = 0
22647 15:43:17.080390 close(5) = 0
and later the HTTP::Response error is "500 Can't connect to prelive:84
(connect: No such file or directory)".
Note that here's an unexpected lstat call, which sets the errno variable
to ENOENT. The if condition in IO::Socket::connect now uses the wrong
branch, and the final error message shows the strange "No such file or
directory" (= stringified ENOENT)
NYTProf.xs does a lstat call in fid_is_pmc(). The attached patch saves
errno before the syscall and restores it afterwards. With the patched
Devel::NYTProf, the strace looks good again:
23737 16:14:37.670286 connect(5, {sa_family=AF_INET, sin_port=htons(84),
sin_addr=inet_addr("172.17.30.1")}, 16) = -1 EINPROGRESS (Operation now
in progress)
23737 16:14:37.670491 lstat64("/usr/lib/perl/5.8/Errno.pmc", 0xbf90440c)
= -1 ENOENT (No such file or directory)
24118 16:20:27.842837 stat64("/etc/perl/IO/Select.pmc", 0xbfa137dc) = -1
ENOENT (No such file or directory)
24118 16:20:27.842875 stat64("/etc/perl/IO/Select.pm", 0xbfa136ec) = -1
ENOENT (No such file or directory)
Now IO::Select was not autoloaded, but it's clear that the correct
branch was chosen.
Regards,
Slaven
Subject: | Devel-NYTProf-errno.patch |
#
#
# To apply this patch:
# STEP 1: Chdir to the source directory.
# STEP 2: Run the 'applypatch' program with this patch file as input.
#
# If you do not have 'applypatch', it is part of the 'makepatch' package
# that you can fetch from the Comprehensive Perl Archive Network:
# http://www.perl.com/CPAN/authors/Johan_Vromans/makepatch-x.y.tar.gz
# In the above URL, 'x' should be 2 or higher.
#
# To apply this patch without the use of 'applypatch':
# STEP 1: Chdir to the source directory.
# STEP 2: Run the 'patch' program with this file as input.
#
#### End of Preamble ####
#### Patch data follows ####
diff -up 'Devel-NYTProf-2.04-JK3cEE/NYTProf.xs' 'new.Devel-NYTProf-2.04/NYTProf.xs'
Index: ./NYTProf.xs
Prereq: 481
--- ./NYTProf.xs Wed Oct 1 17:17:04 2008
+++ ./NYTProf.xs Thu Oct 2 17:07:49 2008
@@ -1007,6 +1007,7 @@ fid_is_pmc(pTHX_ Hash_entry *fid_info)
SV *pmcsv = Perl_newSVpvf(aTHX_ "%s%c", SvPV_nolen(pmsv), 'c');
Stat_t pmstat;
Stat_t pmcstat;
+ int saved_errno = errno;
if (PerlLIO_lstat(SvPV_nolen(pmcsv), &pmcstat) == 0) {
/* .pmc exists, is it newer than the .pm (if that exists) */
if (PerlLIO_lstat(SvPV_nolen(pmsv), &pmstat) < 0 ||
@@ -1014,6 +1015,7 @@ fid_is_pmc(pTHX_ Hash_entry *fid_info)
is_pmc = 1; /* hey, maybe it's Larry working on the perl6 comiler */
}
}
+ SETERRNO(saved_errno, 0);
SvREFCNT_dec(pmcsv);
SvREFCNT_dec(pmsv);
}
#### End of Patch data ####
#### ApplyPatch data follows ####
# Data version : 1.0
# Date generated : Thu Oct 2 17:07:55 2008
# Generated by : makepatch 2.00_12*
# Recurse directories : Yes
# Excluded files : (\A|/).*\~\Z
# (\A|/).*\.a\Z
# (\A|/).*\.bak\Z
# (\A|/).*\.BAK\Z
# (\A|/).*\.elc\Z
# (\A|/).*\.exe\Z
# (\A|/).*\.gz\Z
# (\A|/).*\.ln\Z
# (\A|/).*\.o\Z
# (\A|/).*\.obj\Z
# (\A|/).*\.olb\Z
# (\A|/).*\.old\Z
# (\A|/).*\.orig\Z
# (\A|/).*\.rej\Z
# (\A|/).*\.so\Z
# (\A|/).*\.Z\Z
# (\A|/)\.del\-.*\Z
# (\A|/)\.make\.state\Z
# (\A|/)\.nse_depinfo\Z
# (\A|/)core\Z
# (\A|/)tags\Z
# (\A|/)TAGS\Z
# p 'NYTProf.xs' 97899 1222960069 0100644
#### End of ApplyPatch data ####
#### End of Patch kit [created: Thu Oct 2 17:07:55 2008] ####
#### Patch checksum: 55 2171 2936 ####
#### Checksum: 73 2794 54412 ####