-
Notifications
You must be signed in to change notification settings - Fork 560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
in-place editing in 5.28 quickly exhausts open file descriptor limit #16602
Comments
From mtmiller@debian.orgThis is a bug report for perl from mtmiller@debian.org, The in-place editing feature in perl 5.28 dies with an error if called By way of example: $ for n in $(seq 1 1019); do mktemp XXXXXX > /dev/null; done With the following modified program, one can look into the /proc $ perl -pi -e 's/a/b/; BEGIN {print "$$\n"} END {sleep 60}' * It looks like perl is doing an opendir on the parent directory of each I have verified that this is related to the "safer in-place editing" Flags: Site configuration information for perl 5.28.0: Configured by mike at Sat Jun 30 16:56:57 PDT 2018. Summary of my perl5 (revision 5 version 28 subversion 0) configuration: @INC for perl 5.28.0: Environment for perl 5.28.0: |
From @jkeenanOn Sun, 01 Jul 2018 02:08:43 GMT, mtmiller@debian.org wrote:
I have confirmed all of the above. A very thorough bug report! Thank you very much. -- |
The RT System itself - Status changed from 'new' to 'open' |
From @tonycozOn Sat, Jun 30, 2018 at 07:08:44PM -0700, (via RT) wrote:
Please try the attached patch. Tony |
From @tonycoz0001-perl-133314-always-close-the-directory-handle-on-cle.patchFrom 59c3aff6023b4470506a1a58ff47d7491c758925 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Mon, 2 Jul 2018 10:43:19 +1000
Subject: (perl #133314) always close the directory handle on clean up
Previously the directory handle was only closed if the rest of the
magic free clean up is done, but in most success cases that code
doesn't run, leaking the directory handle.
So always close the directory if our AV is available.
---
doio.c | 56 +++++++++++++++++++++++++++++++-------------------------
1 file changed, 31 insertions(+), 25 deletions(-)
diff --git a/doio.c b/doio.c
index 4b8923f77c..16daf9fd11 100644
--- a/doio.c
+++ b/doio.c
@@ -1163,44 +1163,50 @@ S_argvout_free(pTHX_ SV *io, MAGIC *mg) {
/* mg_obj can be NULL if a thread is created with the handle open, in which
case we leave any clean up to the parent thread */
- if (mg->mg_obj && IoIFP(io)) {
- SV **pid_psv;
+ if (mg->mg_obj) {
#ifdef ARGV_USE_ATFUNCTIONS
SV **dir_psv;
DIR *dir;
+
+ dir_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_ORIG_DIRP, FALSE);
+ assert(dir_psv && *dir_psv && SvIOK(*dir_psv));
+ dir = INT2PTR(DIR *, SvIV(*dir_psv));
#endif
- PerlIO *iop = IoIFP(io);
+ if (IoIFP(io)) {
+ SV **pid_psv;
+ PerlIO *iop = IoIFP(io);
- assert(SvTYPE(mg->mg_obj) == SVt_PVAV);
+ assert(SvTYPE(mg->mg_obj) == SVt_PVAV);
- pid_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_ORIG_PID, FALSE);
+ pid_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_ORIG_PID, FALSE);
- assert(pid_psv && *pid_psv);
+ assert(pid_psv && *pid_psv);
- if (SvIV(*pid_psv) == (IV)PerlProc_getpid()) {
- /* if we get here the file hasn't been closed explicitly by the
- user and hadn't been closed implicitly by nextargv(), so
- abandon the edit */
- SV **temp_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_TEMP_NAME, FALSE);
- const char *temp_pv = SvPVX(*temp_psv);
+ if (SvIV(*pid_psv) == (IV)PerlProc_getpid()) {
+ /* if we get here the file hasn't been closed explicitly by the
+ user and hadn't been closed implicitly by nextargv(), so
+ abandon the edit */
+ SV **temp_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_TEMP_NAME, FALSE);
+ const char *temp_pv = SvPVX(*temp_psv);
- assert(temp_psv && *temp_psv && SvPOK(*temp_psv));
- (void)PerlIO_close(iop);
- IoIFP(io) = IoOFP(io) = NULL;
+ assert(temp_psv && *temp_psv && SvPOK(*temp_psv));
+ (void)PerlIO_close(iop);
+ IoIFP(io) = IoOFP(io) = NULL;
#ifdef ARGV_USE_ATFUNCTIONS
- dir_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_ORIG_DIRP, FALSE);
- assert(dir_psv && *dir_psv && SvIOK(*dir_psv));
- dir = INT2PTR(DIR *, SvIV(*dir_psv));
- if (dir) {
- if (unlinkat(my_dirfd(dir), temp_pv, 0) < 0 &&
- NotSupported(errno))
- (void)UNLINK(temp_pv);
- closedir(dir);
- }
+ if (dir) {
+ if (unlinkat(my_dirfd(dir), temp_pv, 0) < 0 &&
+ NotSupported(errno))
+ (void)UNLINK(temp_pv);
+ }
#else
- (void)UNLINK(temp_pv);
+ (void)UNLINK(temp_pv);
#endif
+ }
}
+#ifdef ARGV_USE_ATFUNCTIONS
+ if (dir)
+ closedir(dir);
+#endif
}
return 0;
--
2.11.0
|
From @tonycozOn Mon, Jul 02, 2018 at 11:04:41AM +1000, Tony Cook wrote:
You might need to edit the leading > that some mail system along the Tony |
From @karenetheridgeSince this is a regression, this fix should be included in the 5.28.1 maint release. |
From @jkeenanOn Mon, 02 Jul 2018 01:15:56 GMT, tonyc wrote:
Patch worked for me. Please find attached a first attempt at a test for this behavior. Thank you very much. |
From @jkeenan133314-0002-Test-correction-to-safe-in-place-editing.patchFrom d78516390da9389e32b2ca9330b8fc92c84eb59c Mon Sep 17 00:00:00 2001
From: James E Keenan <jkeenan@cpan.org>
Date: Sun, 1 Jul 2018 22:25:59 -0400
Subject: [PATCH] Test correction to safe in-place editing.
For: RT 133314
---
t/run/switches.t | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/t/run/switches.t b/t/run/switches.t
index 7ccef1e..c87d016 100644
--- a/t/run/switches.t
+++ b/t/run/switches.t
@@ -12,7 +12,7 @@ BEGIN {
BEGIN { require "./test.pl"; require "./loc_tools.pl"; }
-plan(tests => 137);
+plan(tests => 138);
use Config;
@@ -699,3 +699,23 @@ SWTEST
);
like( $r, qr/ok/, 'Spaces on the #! line (#30660)' );
}
+
+# RT #133314
+
+{
+ my $count = 1020;
+ my $fcount = sprintf("%04d" => $count);
+ print STDOUT "XXX: ", (join '|' => $count, $fcount), "\n";
+ for (my $i=1; $i<=$count; $i++) {
+ my $tfile = (-d "t" ? "t/" : ""). "switches.133314.$$.$fcount.tmp";
+ open my $f, ">$tfile" or skip("Can't write temp file $tfile: $!");
+ close $f;
+ push @tmpfiles, $tfile;
+ }
+ $r = runperl(
+ switches => [ '-pi' ],
+ prog => 's/a/b/',
+ args => [ "*switches.133314.*" ],
+ ),
+ is( $r, '', "RT \#133314: Safe in-place editing can handle at least $count files");
+}
--
2.7.4
|
From @ilmari"James E Keenan via RT" <perlbug-followup@perl.org> writes:
The exact value at which it fails will depend on the number of otherwise - ilmari |
From mtmiller@debian.orgThe patch works for me, thank you very much for the quick fix. On Mon, Jul 02, 2018 at 03:41:16 -0700, Dagfinn Ilmari Mannsåker wrote:
Agree with that. Maybe a more robust test would be for Perl to inspect END { open my $f, ">/dev/null"; fileno($f) < 10 or die; close($f); } -- |
From @tonycozOn Mon, 02 Jul 2018 21:08:37 -0700, mtmiller@debian.org wrote:
It turned out not to be quite this simple, but it's a good approach. Applied a new test in 028f02e and the original fix as 3d5e9c1. At this point I don't think the test should be backported, since it may contain assumptions that break on some platform. Tony |
From @steve-m-hayThis was fixed in blead by commit 3d5e9c1, and back-ported to 5.28.1 by commit e0eae03. Awaiting release in 5.30.0. |
@steve-m-hay - Status changed from 'open' to 'pending release' |
From @khwilliamsonThank you for filing this report. You have helped make Perl better. With the release today of Perl 5.30.0, this and 160 other issues have been Perl 5.30.0 may be downloaded via: If you find that the problem persists, feel free to reopen this ticket. |
@khwilliamson - Status changed from 'pending release' to 'resolved' |
Migrated from rt.perl.org#133314 (status was 'resolved')
Searchable as RT133314$
The text was updated successfully, but these errors were encountered: