Bug 13311 - xargs: fdleak.c:396: complain_about_leaky_fds: Assertion `no_leaks' failed.
Summary: xargs: fdleak.c:396: complain_about_leaky_fds: Assertion `no_leaks' failed.
Status: RESOLVED FIXED
Alias: None
Product: Pseudo
Classification: Yocto Project Subprojects
Component: pseudo (show other bugs)
Version: 2.6.1
Hardware: PC Multiple
: Medium+ normal
Target Milestone: 4.2 M4
Assignee: Yoann Congal
QA Contact:
URL:
Whiteboard:
Depends on:
Blocks:
 
Reported: 2019-04-30 10:25 UTC by Pavel Modilaynen
Modified: 2023-03-07 13:42 UTC (History)
7 users (show)

See Also:
OS type for building Yocto: ---
Type of Regression: ---
Verified:
Documentation change: No (bug/feature does not impact docs)


Attachments
patch that fixes fd leak (962 bytes, patch)
2019-04-30 10:25 UTC, Pavel Modilaynen
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Pavel Modilaynen 2019-04-30 10:25:44 UTC
Created attachment 4510 [details]
patch that fixes fd leak

Any package build fails with
-------------
The stack trace of python calls that resulted in this exception/failure was:
File: 'exec_python_func() autogenerated', lineno: 2, function: <module>
     0001:
 *** 0002:extend_recipe_sysroot(d)
     0003:
File: 'DDD/meta/classes/staging.bbclass', lineno: 559, function: extend_recipe_sysroot
     0555:    bb.note("Installed into sysroot: %s" % str(msg_adding))
     0556:    bb.note("Skipping as already exists in sysroot: %s" % str(msg_exists))
     0557:
     0558:    for f in fixme:
 *** 0559:        staging_processfixme(fixme[f], f, recipesysroot, recipesysrootnative, d)
     0560:
     0561:    for p in postinsts:
     0562:        subprocess.check_output(p, shell=True, stderr=subprocess.STDOUT)
     0563:
File: 'DDD/meta/classes/staging.bbclass', lineno: 174, function: staging_processfixme
     0170:    for fixmevar in ['COMPONENTS_DIR', 'HOSTTOOLS_DIR', 'PKGDATA_DIR', 'PSEUDO_LOCALSTATEDIR', 'LOGFIFO']:
     0171:        fixme_path = d.getVar(fixmevar)
     0172:        cmd += " -e 's:FIXME_%s:%s:g'" % (fixmevar, fixme_path)
     0173:    bb.debug(2, cmd)
 *** 0174:    subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
     0175:
     0176:
     0177:def staging_populate_sysroot_dir(targetsysroot, nativesysroot, native, d):
     0178:    import glob
File: '/usr/lib/python3.5/subprocess.py', lineno: 316, function: check_output
     0312:        # empty string. That is maintained here for backwards compatibility.
     0313:        kwargs['input'] = '' if kwargs.get('universal_newlines', False) else b''
     0314:
     0315:    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
 *** 0316:               **kwargs).stdout
     0317:
     0318:
     0319:class CompletedProcess(object):
     0320:    """A process that has finished running.
File: '/usr/lib/python3.5/subprocess.py', lineno: 398, function: run
     0394:            raise
     0395:        retcode = process.poll()
     0396:        if check and retcode:
     0397:            raise CalledProcessError(retcode, process.args,
 *** 0398:                                     output=stdout, stderr=stderr)
     0399:    return CompletedProcess(process.args, retcode, stdout, stderr)
     0400:
     0401:
     0402:def list2cmdline(seq):
Exception: subprocess.CalledProcessError: Command 'sed -e 's:^[^/]*/:DDD/WWW/tmp/work/cortexa9hf-neon-poky-linux-gnueabi/perl/5.24.4-r0/recipe-sysroot-native/:g' DDD/WWW/tmp/sysroots-components/x86_64/rpm-native/fixmepath DDD/WWW/tmp/sysroots-components/x86_64/pkgconfig-native/fixmepath DDD/WWW/tmp/sysroots-components/x86_64/elfutils-native/fixmepath DDD/WWW/tmp/sysroots-components/x86_64/dbus-native/fixmepath DDD/WWW/tmp/sysroots-components/x86_64/python3-native/fixmepath DDD/WWW/tmp/sysroots-components/x86_64/openssl-native/fixmepath DDD/WWW/tmp/sysroots-components/x86_64/nspr-native/fixmepath DDD/WWW/tmp/sysroots-components/x86_64/e2fsprogs-native/fixmepath DDD/WWW/tmp/sysroots-components/x86_64/ncurses-native/fixmepath | xargs sed -i -e 's:FIXMESTAGINGDIRTARGET:DDD/WWW/tmp/work/cortexa9hf-neon-poky-linux-gnueabi/perl/5.24.4-r0/recipe-sysroot:g; s:FIXMESTAGINGDIRHOST:DDD/WWW/tmp/work/cortexa9hf-neon-poky-linux-gnueabi/perl/5.24.4-r0/recipe-sysroot-native:g' -e 's:FIXME_COMPONENTS_DIR:DDD/WWW/tmp/sysroots-components:g' -e 's:FIXME_HOSTTOOLS_DIR:DDD/WWW/tmp/hosttools:g' -e 's:FIXME_PSEUDO_LOCALSTATEDIR:DDD/WWW/tmp/work/cortexa9hf-neon-poky-linux-gnueabi/perl/5.24.4-r0/pseudo/:g' -e 's:FIXME_LOGFIFO:DDD/WWW/tmp/work/cortexa9hf-neon-poky-linux-gnueabi/perl/5.24.4-r0/temp/fifo.3940:g'' returned non-zero exit status 125

Subprocess output:
xargs: File descriptor 8 will leak; please report this as a bug, remembering to include a detailed description of the simplest way to reproduce this problem.
xargs: fdleak.c:396: complain_about_leaky_fds: Assertion `no_leaks' failed.
xargs: sed: terminated by signal 6
-------------

when building with enabled and redirected pseudo logging:
conf/local.conf:

FAKEROOTENV_append = " PSEUDO_DEBUG=7 PSEUDO_DEBUG_FILE=<>/pseudolog/pseudo_dbg.log"

I've tracked down this issue and found that file descriptor 8 belong to pseudo log file descriptor itself which is leaked when xargs performs exec.
So, with the attached patch I propose to add O_CLOEXEC flag to automatically close file descriptor on forking new process with fork/exec. 

NB
I set version to 2.6.1 but I am using the latest pseudo SRCREV in bbappend with 
SRCREV = "3fa7c853e0bcd6fe23f7524c2a3c9e3af90901c3"

thus it's applicable to master.
Comment 1 Pavel Modilaynen 2019-04-30 11:31:04 UTC
I found that this issue was actually reported to findutils bug tracker https://savannah.gnu.org/bugs/?47220 however considering my findings this is not related to findutils (or xargs in particular) because fd leak does occur in pseudo.

As a side note, I wanted to mention that there is environment variable GNU_FINDUTILS_FD_LEAK_CHECK that enables fd leak check for "find" only for some reason. I thought "xargs" could utilize that too and proposed https://savannah.gnu.org/patch/?9799.
Comment 2 Seebs 2019-04-30 18:24:04 UTC
Thanks, I think you're almost certainly right, and I'll try to have a look at this more closely. But yeah, I think that is an fd leak. Good catch, thanks!
Comment 3 Randy MacLeod 2020-01-16 16:16:28 UTC
Grace/Mingli please apply the patch, test and send a commit since seebs isn't getting to this.
Comment 4 Mingli Yu 2020-01-17 07:24:48 UTC
The findutils 4.7.0 which includes the commit https://git.savannah.gnu.org/cgit/findutils.git/commit/?id=5699fb78d44a9f5064f98459178ee8e7fa159645 fixs the issue, I will upgrade findutils to 4.7.0 then.
Comment 5 Pavel Modilaynen 2020-01-17 10:37:38 UTC
Sorry Mingli, but that is not the fix, fd's are still leaking, it's just not visible after the fix (if GNU_FINDUTILS_FD_LEAK_CHECK is not set).
Comment 6 Mingli Yu 2020-01-19 05:16:25 UTC
(In reply to comment #5)
> Sorry Mingli, but that is not the fix, fd's are still leaking, it's just not
> visible after the fix (if GNU_FINDUTILS_FD_LEAK_CHECK is not set).

Have sent the patch to http://git.yoctoproject.org/cgit/cgit.cgi/pseudo/ to ask merge the fix to pseudo git repo.
Comment 7 Randy MacLeod 2020-02-13 15:59:33 UTC
Any update?
Comment 8 Randy MacLeod 2020-12-16 01:59:42 UTC
We shouldn't wait for 3.4 to fix this so I've moved the target to 3.3-M3. Richard is CCed now since he has been merging commits into pseudo. Mingli, please resend.
Comment 9 Randy MacLeod 2022-02-03 16:37:17 UTC
Mingli, please update the status of this bug. Is the patch in pseudo and/or oe-core?
Comment 10 Randy MacLeod 2022-03-23 00:43:07 UTC
Mingli is not able to work on this defect so I've changed it to unassigned.
Comment 11 Yoann Congal 2023-02-28 23:02:46 UTC
There was a discussion here : https://lists.openembedded.org/g/openembedded-core/topic/72391928 (on the patch mail subject)

Mingli did try to send the patch again here : https://lists.openembedded.org/g/openembedded-core/message/133813

Apparently, it was not merged.

> Is the patch in pseudo and/or oe-core?

No. It's not : https://git.yoctoproject.org/pseudo/tree/pseudo_util.c#n1614
  fd = open(pseudo_path, O_WRONLY | O_APPEND | O_CREAT, 0644);
=> does not contains O_CLOEXEC added by the patch

I'll try to reproduce the bug and check if Pavel's patch still fixes it.
Comment 12 Yoann Congal 2023-02-28 23:30:54 UTC
Reproduced with :

SUMMARY = "bug-13311-repro"
LICENSE = "CLOSED"

FAKEROOTENV:append = " PSEUDO_DEBUG=7 PSEUDO_DEBUG_FILE=/tmp/pseudo_dbg.log"

do_install() {
    set -x
    echo test > ${D}/a
    export GNU_FINDUTILS_FD_LEAK_CHECK=1
    cat ${D}/a
    find ${D} -type f -exec sed -i "s/test/&ed/" '{}' \;
    cat ${D}/a
    ls -1 ${D}/* | xargs sed -i "s/test/&ed/"
    cat ${D}/a

    rm ${D}/a
}

=> do_install fails with :
| find: File descriptor 10 will leak; please report this as a bug, remembering to include a detailed description of the simplest way to reproduce this problem.
| find: fdleak.c:396: complain_about_leaky_fds: Assertion `no_leaks' failed.
| find: ‘sed’ terminated by signal 6
.../...
| xargs: File descriptor 8 will leak; please report this as a bug, remembering to include a detailed description of the simplest way to reproduce this problem.
| xargs: fdleak.c:396: complain_about_leaky_fds: Assertion `no_leaks' failed.
| xargs: sed: terminated by signal 6
Comment 13 Yoann Congal 2023-03-01 00:13:26 UTC
Pavel's patch still applies and fix the bug.

Sent on ML here : 
* https://lists.openembedded.org/g/openembedded-core/message/177860 (cover)
* https://lists.openembedded.org/g/openembedded-core/message/177861
Comment 15 Yoann Congal 2023-03-07 10:34:12 UTC
Moving to 4.2 M4