Bug 504926

Summary: possible expect fd leak when spawn
Product: [Fedora] Fedora Reporter: Tim Taiwanese Liim <tim.liim>
Component: expectAssignee: Vitezslav Crhonek <vcrhonek>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: 10CC: vcrhonek
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2009-09-09 09:02:09 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Tim Taiwanese Liim 2009-06-10 03:30:47 UTC
Description of problem:
    It seems that spawn has fd leak with /dev/null, as illustrated by
    example code.  If you see the example code is invalid, feel free to
    close this bug.

Version-Release number of selected component (if applicable):
    expect-5.43.0-15.fc10.x86_64

How reproducible:
    always

Steps to Reproduce:
    1. create t.tcl with this content:
        #!/usr/bin/expect
        while (1) {
            spawn sleep 1
            expect eof {}
        }

    2. run t.tcl
    3. in another terminal, run
        ls -l /proc/$(pgrep t.tcl)/fd
  
Actual results:
    The number of fd grows one per second.  Eventually the
    script dies after running out of fd.

Expected results:
    The number of fd should be bounded.

Additional info:
    n/a

Comment 1 Vitezslav Crhonek 2009-09-09 09:02:09 UTC
Hi,
The code is invalid. Actually, you are creating zombie process every single second. Run your script and see output of "ps aux":

14310 pts/1    S+     0:00 /usr/bin/expect ./t.tcl
14312 ?        Zs     0:00 [sleep] <defunct>
14316 ?        Zs     0:00 [sleep] <defunct>
14320 ?        Zs     0:00 [sleep] <defunct>
14325 ?        Zs     0:00 [sleep] <defunct>
14330 ?        Zs     0:00 [sleep] <defunct>
...

You should reap the sleep processes - modify your script to:
#!/usr/bin/expect
while {1} {
    spawn sleep 1
    expect eof {}
    wait
}

Check "ps aux" and "ls -l /proc/$(pgrep t.tcl)/fd" - looks better, right?;)

Comment 2 Tim Taiwanese Liim 2009-09-10 18:08:45 UTC
Vitezslav,
Thanks for pointing my user error!  Good, so there is no bug.  I
wondered if we can add this to 'man expect', somewhere around the
'spawn' command, that one needs to use 'wait' to reap the spawned
process.

Comment 3 Vitezslav Crhonek 2009-09-21 12:51:14 UTC
Well, it's mentioned near the 'close' command in man page:

"No  matter  whether the connection is closed implicitly or explicitly, you should call wait to clear up the corresponding kernel process slot. close does not call wait since there is no guarantee that closing a process connection will cause it to exit. See wait below for more info."

Of course, when the script is finished, everything is reaped automatically.

But the man page is meant primarily as reference material. If you need/want to learn how to use Expect effectively and in full range, I recommend you the book written by author of Expect Don Libes - "Exploring Expect".

Comment 4 Tim Taiwanese Liim 2009-09-21 15:10:32 UTC
Vitezslav,
Thanks for info!  Understand now.