From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.bugs Subject: bug#13079: 24.3.50; Emacs cannot create subprocess Date: Wed, 05 Dec 2012 19:29:58 +0200 Message-ID: <83wqwwpfu1.fsf@gnu.org> References: <83ehj5r2gs.fsf@gnu.org> Reply-To: Eli Zaretskii NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1354728669 32368 80.91.229.3 (5 Dec 2012 17:31:09 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 5 Dec 2012 17:31:09 +0000 (UTC) Cc: 13079@debbugs.gnu.org To: Li Zhai Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Dec 05 18:31:22 2012 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1TgIoa-0006iY-KU for geb-bug-gnu-emacs@m.gmane.org; Wed, 05 Dec 2012 18:31:20 +0100 Original-Received: from localhost ([::1]:55761 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TgIoO-0005eu-O5 for geb-bug-gnu-emacs@m.gmane.org; Wed, 05 Dec 2012 12:31:08 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:60920) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TgIoG-0005Zp-K7 for bug-gnu-emacs@gnu.org; Wed, 05 Dec 2012 12:31:06 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TgIoA-00018p-5p for bug-gnu-emacs@gnu.org; Wed, 05 Dec 2012 12:31:00 -0500 Original-Received: from debbugs.gnu.org ([140.186.70.43]:44975) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TgIo9-00017Q-Nq for bug-gnu-emacs@gnu.org; Wed, 05 Dec 2012 12:30:54 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1TgIoH-0004ML-Le for bug-gnu-emacs@gnu.org; Wed, 05 Dec 2012 12:31:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Eli Zaretskii Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 05 Dec 2012 17:31:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 13079 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 13079-submit@debbugs.gnu.org id=B13079.135472862016705 (code B ref 13079); Wed, 05 Dec 2012 17:31:01 +0000 Original-Received: (at 13079) by debbugs.gnu.org; 5 Dec 2012 17:30:20 +0000 Original-Received: from localhost ([127.0.0.1]:55226 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TgInc-0004LO-7g for submit@debbugs.gnu.org; Wed, 05 Dec 2012 12:30:20 -0500 Original-Received: from mtaout21.012.net.il ([80.179.55.169]:41919) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TgInX-0004LC-QN for 13079@debbugs.gnu.org; Wed, 05 Dec 2012 12:30:17 -0500 Original-Received: from conversion-daemon.a-mtaout21.012.net.il by a-mtaout21.012.net.il (HyperSendmail v2007.08) id <0MEK00C00IFXG600@a-mtaout21.012.net.il> for 13079@debbugs.gnu.org; Wed, 05 Dec 2012 19:29:59 +0200 (IST) Original-Received: from HOME-C4E4A596F7 ([87.69.4.28]) by a-mtaout21.012.net.il (HyperSendmail v2007.08) with ESMTPA id <0MEK00CMLJ9X9LB0@a-mtaout21.012.net.il>; Wed, 05 Dec 2012 19:29:57 +0200 (IST) In-reply-to: X-012-Sender: halo1@inter.net.il X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:67975 Archived-At: > Date: Wed, 5 Dec 2012 10:26:51 +0800 > From: Li Zhai > Cc: 13079@debbugs.gnu.org > > I mean, emacs display the messages before the loop ends. And all the > processes are gone, emacs did not wait them to exit. Emacs doesn't wait because you told it so, by using zero as the 5th argument to call-process-region. This is normal. > I've tried two different version from > http://ftp.gnu.org/gnu/emacs/windows/emacs-23.4-bin-i386.zip and > http://alpha.gnu.org/gnu/emacs/windows/emacs-20120917-r110062-bin-i386.zip > > Here is how to reproduce the bug: > > 1. Open the emacs using ``emacs -Q'' > > 2. paste the code into *scratch* buffer: > > (progn > (dotimes (i 35) > (call-process-region (point-min) (point-min) "ddeclient" t 0 nil > "SUMATRA" "control") > (message "%d" i))) > > the *ONLY* difference between the previous code is I increase the > repeat times to call the function `call-process-region'. Here is 35 > times, you could try to increase the number lager if the bug not > reproducing. > > 3. Eval the code using C-x C-e > > 4. You should see the emacs report an error: > > Debugger entered--Lisp error: (file-error "Spawning child process" > "resource temporarily unavailable") This is not a bug, but a known limitation of Emacs on Windows. The way management of subprocesses is implemented on Windows, Emacs can only have 32 subprocesses simultaneously at any given time (because it watches two separate handles for each subprocess, and uses an API that supports maximum of 64 handles). So this is also normal. If you use 32 instead of 35, the above error message will not appear. But that won't solve the _real_ problem here, see below. > 5. Quit the elisp debugger and execute the code again(press C-x C-e), > this time emacs should report: > > Debugger entered--Lisp error: (file-error "Opening output file" > "permission denied" "c:/Users/iot003/Desktop/emacs-24.2.50/bin") > call-process-region(1 1 "ddeclient" t 0 nil "SUMATRA" "control") > > 6. Quit the elisp debugger. This time, emacs cannot create any > sub-process any more. Try to execute a shell command by press `M-! > ls', you will find it out. > > This problem occurred more often on my private build version. I guess > the problem is the default stack size assigned by compiler is too > small. No, this has nothing to do with something fancy like stack size, it's a much more mundane problem. It's because we fail to create temporary files needed by call-process-region and commands that use it. Did you look in your TEMP directory? I bet you have gobs of emXYZZY files there, exactly 42 of them per each time you tried this stuff. The immediate reason for the mysterious "permission denied" error (about a directory!) is that call-process-region was not checking whether the call to 'mktemp' failed. When that function fails, it produces an empty "file name", and call-process-region was boldly using that as a file name, eventually trying to open a directory, which on Windows fails with EACCES. This part was easy to fix: starting with revision 110996 on the emacs-24 branch, Emacs now produces a more intelligent error message in this case. The harder part of this bug is the reason _why_ 'mktemp' fails. Your command launches asynchronous subprocesses, creating a temporary file for each one of them where Emacs puts the contents of the region. In this case, call-process-region arranges for the temporary files to be removed when the call to call-process returns, and then calls call-process. However, since this is an async subprocess, call-process returns immediately, without waiting for the subprocess to exit, and Emacs deletes the temporary file. This "cleanup" uses the non-portable (outside of Posix filesystems) trick of deleting a file while it is still open and used by the child process. On Windows, this attempt to delete the file fails, and the file is left behind. The other part of this puzzle is that 'mktemp' as implemented by the Windows runtime can only have up to 42 simultaneous temporary files per calling thread (the MSDN documentation says 26, but that's a lie). Once there are 42 files in your TEMP directory created by a single Emacs session, all the future calls to 'mktemp' from the same session will fail, unless you manually delete those files. This part of the bug is harder to solve, because some code needs to be implemented that will defer deletion until the process exits. So it is not solved yet. But at least you now have a work-around: manually delete temporary em* files from your TEMP directory.