Subject: bug#19868: #19868 25.0.50; Compilation eats buffers

From: Noam Postavsky <[email-masked]>
Date: Mon, 29 Aug 2016 17:48:30 -0400

On Wed, Aug 17, 2016 at 11:15 AM, Eli Zaretskii <[email-masked]> wrote:
>> I printed all open_fd values from deactivate_process, just before the
>> closing loop, I got
>>
>> deactivate_process()open_fd[0] = -1, open_fd[1] = 4, open_fd[2] = 5,
>> open_fd[3] = -1, open_fd[4] = -1, open_fd[5] = -1,
>>
>> So, only WRITE_TO_SUBPROCESS and READ_FROM_SUBPROCESS are open. When
>> compiling bug.c without -mwindows, all open_fd values are -1 at that
>> spot.
>
> The last sentence shows an important difference between the two
> cases.  Can you spot the code which makes the 2 handles -1 in the case
> of a console (not -mwindows) application?  That might give us a clue
> about the reason for Emacs hanging in _close.

Sorry, turns out I lied about this. In the non-mwindows case
deactivate_process() gets called 3 times in total, the latter 2 times
have all the handles closed and set to -1 (and I mistakenly looked at
the values only from the last call). The first time is the same as the
mwindows case (except for the hanging, of course).

> Another thing to try is to set w32-start-process-share-console to a
> non-nil value.

Seems to make no difference.

>> Another observation: if I close Emacs while it's running bug.exe,
>> Emacs closes successfully, but leaves bug.exe running (even though I
>> answer yes at the prompt to kill it).
>
> That's just another manifestation of the fact that we cannot reliably
> kill grandchildren processes on MS-Windows, especially when they are
> not console applications.  We can only kill the immediate child
> process, in this case cmdproxy (and probably its child cmd.exe as
> well).

Right, I recall seeing in #15983 a suggestion to crawl the process
tree in order to be able to do this. Another possibility I found while
searching the web is to use Job Objects for this
(https://msdn.microsoft.com/en-us/library/ms684161(VS.85).aspx).
Though it has a limitation:

Windows 7, Windows Server 2008 R2, Windows XP with SP3, Windows Server
2008, Windows Vista and Windows Server 2003:  A process can be
associated with only one job. Jobs cannot be nested. The ability to
nest jobs was added in Windows 8 and Windows Server 2012.

So Emacs using Job Objects would prevent the process it calls from
using them (on older Windows OSes).

>
> P.S. Don't hesitate to ask questions about how this stuff works, if
> something is unclear.  There's a large comment around line 390 in
> w32proc.c which provides an overview, so if you didn't already read
> it, it could help.

For the record, the comment seems to be closer to line 790 (after the first ^L).