Commit: Tell users when the plugin interface runs out of file descriptors
Nick Clifton
nickc@redhat.com
Wed May 19 10:53:09 GMT 2021
Hi Guys,
I am applying the patch below which is half bug-fix half-hack. The
problem is that the plugin API can run out of file descriptors when
performing a very large link. (This was discovered when using ld.bfd
to link LLVM...) When this happens the bfd_plugin_open_input()
function returns 0, which in turn leads to an error message about the
format of an input file being unrecognizable. This is obviously
wrong, and the first part of this patch detects this case and issues a
second, more explanatory error message.
A better solution of course would be to recycle the file descriptors
rather than allocating two per input file and two per member of an
incoming archive. But try as I might, I have not found a way to do
this without breaking the plugin API. So instead the hacky part of
the patch attempts to increase the limit on the number of open file
descriptors, in order to allow the link to continue. This works for
the test case mentioned above, but will fail one day. Still at least
it works for now.
Cheers
Nick
bfd/ChangeLog
2021-05-19 Nick Clifton <nickc@redhat.com>
* plugin.c (bfd_plugin_open_input): Inform the user if the limit
on the number of open files is reached. If possible, try to
increase this limit before failing.
diff --git a/bfd/plugin.c b/bfd/plugin.c
index c4f2be8999e..1fee4d0c870 100644
--- a/bfd/plugin.c
+++ b/bfd/plugin.c
@@ -209,7 +209,35 @@ bfd_plugin_open_input (bfd *ibfd, struct ld_plugin_input_file *file)
the same underlying file descriptor. */
file->fd = open (file->name, O_RDONLY | O_BINARY);
if (file->fd < 0)
- return 0;
+ {
+#ifndef EMFILE
+ return 0;
+#else
+ if (errno != EMFILE)
+ return 0;
+
+#ifdef HAVE_GETRLIMIT
+ struct rlimit lim;
+
+ /* Complicated links involving lots of files and/or large archives
+ can exhaust the number of file descriptors available to us.
+ If possible, try to allocate more descriptors. */
+ if (getrlimit (RLIMIT_NOFILE, & lim) == 0
+ && lim.rlim_cur < lim.rlim_max)
+ {
+ lim.rlim_cur = lim.rlim_max;
+ if (setrlimit (RLIMIT_NOFILE, &lim) == 0)
+ file->fd = open (file->name, O_RDONLY | O_BINARY);
+ }
+
+ if (file->fd < 0)
+#endif
+ {
+ _bfd_error_handler (_("plugin framework: out of file descriptors. Try using fewer objects/archives\n"));
+ return 0;
+ }
+#endif
+ }
if (iobfd == ibfd)
{
More information about the Binutils
mailing list