Bug 44800 - Windows console signals
Summary: Windows console signals
Status: RESOLVED FIXED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mpm_winnt (show other bugs)
Version: 2.2.8
Hardware: PC Windows 2000
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords: PatchAvailable
Depends on:
Blocks:
 
Reported: 2008-04-10 08:44 UTC by Tom Donovan
Modified: 2008-06-05 12:18 UTC (History)
0 users



Attachments
branches/2.2.x patch (4.13 KB, patch)
2008-04-10 08:44 UTC, Tom Donovan
Details | Diff
trunk patch (4.50 KB, patch)
2008-04-10 08:44 UTC, Tom Donovan
Details | Diff
branches/2.2.x patch (4.15 KB, patch)
2008-04-10 19:58 UTC, Tom Donovan
Details | Diff
trunk patch (4.53 KB, patch)
2008-04-10 20:00 UTC, Tom Donovan
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Donovan 2008-04-10 08:44:08 UTC
Created attachment 21808 [details]
branches/2.2.x patch

Starting with Apache 2.2.8, Windows console signal handlers no longer work and the Apache console window has no message loop (i.e. it is never repainted when uncovered). This is due to a change to mpm_winnt.c which creates a "NUL" stdout handle for both parent & child processes.  This change was SVN /trunk rev 609354 and /branches/2.2.x rev 609712.

After change 609354, console signals are no longer delivered to the parent process.  Specifically: CTRL_BREAK_EVENT which triggers an Apache restart; and CTRL_C_EVENT, CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT which trigger an Apache shutdown.

The attached patch creates all Apache child processes with a "NUL" stdout at their inception, but leaves the parent process with its original stdout intact when Apache is not started as a service.  

Note that there is pre-existing code to supply a "NUL" stdout for the parent process when Apache runs as a service without console handles, and the parent process has no need to catch console signals when running as a Windows service - so Apache behavior as a service remains unchanged.

This patch causes the parent to re-declare its console signal handler after every restart.  Some libraries used by modules (like perl5xx.dll) declare a signal handler which terminates the process on CTRL_BREAK_EVENT or CTRL_C_EVENT.  This is the reason Apache could only perform one graceful restart when mod_perl was used on Windows.  By re-declaring Apache's parent signal handler after each (re-)configuration, the Apache parent process can catch, handle, and dismiss these signals before any other library's handler can cause the parent process to exit and leave an orphaned Apache child process.

This patch creates a new copy of the _environ array to pass to apr_proc_create instead of trying to re-use a static copy for subsequent child creations. The comment in mpm_winnt.c that "it won't change for the lifetime of this parent process" is not always true.  If a module adds or changes any Windows environment variable during configuration, the _environ array might be realloc'd causing the static copy to have invalid pointers.

This patch works with Apache 2.2.8 and mod_perl 2.0.3/AS_Perl 5.8.8 and mod_perl 2.0.4rc1/AS_Perl 5.10.0 on Win2k, WinXP, and Vista.  rotatelogs (for both error and access logs) is observed to work correctly through restarts and to terminate completely on shutdown.  Builds with VC6, VS2005 and VS2008 were tested.
Comment 1 Tom Donovan 2008-04-10 08:44:48 UTC
Created attachment 21809 [details]
trunk patch
Comment 2 Tom Donovan 2008-04-10 19:58:22 UTC
Created attachment 21812 [details]
branches/2.2.x patch

do not enable signals if service
Comment 3 Tom Donovan 2008-04-10 20:00:33 UTC
Created attachment 21813 [details]
trunk patch

do not enable signals if service

Although setting the console signal handler appears to be benign on most systems, it is probably safer to never call mpm_start_console_handler() when running as a service.
Comment 4 William A. Rowe Jr. 2008-05-06 13:38:08 UTC
Of course each time this behavior is changed, some use cases win, others will
be broken.  So I'm giving this patch all due consideration.

Note that the third stanza of this patch should be committed independently
of the remainder of this patch, as the unconditional correction of the env array
has nothing to do with the rest of this patches purpose.

If nobody beats me to committing that third stanza I'll get to it once I have
reliable connectivity, and finish reviewing the implications of the rest of
this patch.  I'm especially interested in how it impacts the httpd test framework
which applies this sort of use case.

Given that -X is already defined and correctly handles this case, I'm still not
in agreement yet with committing the remainder of this patch, however it's hard
to argue that apache -k stop simply does not work in console mode, so some fix
is demanded.  I'm tempted to agree with applying this patch on the 2.2 branch
but migrate to the proper behavior as of the trunk/2.4 branch, following the
principal of least astonishment.

Comment 5 William A. Rowe Jr. 2008-06-05 12:18:58 UTC
This is committed as submitted in 3 parts to 2.0 and 2.2.  The third part was
not committed to trunk, these first common commits were...

URL: http://svn.apache.org/viewvc?rev=663669&view=rev
For winnt_mpm console mode, always reset our console handler to be the first,
even on a restart, because some modules (e.g. mod_perl) might have set a console
handler to terminate the process.

URL: http://svn.apache.org/viewvc?rev=663699&view=rev
The environment may be manipulated by modules such as mod_perl, so regenerate
the passed env argument on each CreateProcess call.

The third commit to 2.2 and 2.0 reverts the "regression" you observed for those
users of 2.0 and 2.2 who have observed breakage in their anticipated use case;

URL: http://svn.apache.org/viewvc?rev=663704&view=rev
httpd-2.2 and -2.0 specific patch to revert to 2.0.55/2.2.0 handling of the
stdout channel; do not close stdout in the parent process or reassign it to
\\Device\Null, but keep it open so that the console signal handler continues
to interact with the running "daemonized" httpd process.

Not committed to httpd-2.x; there is disagreement as to whether this is good
behavior for a daemon, and the proper 2.4(3.0) behavior on Win32 may be to
daemonize but properly handle -k stop by the PID file contents.  Many have
asked for this feature who run a minimal httpd.exe, especially from some
removeable media such as CD, and wish to be able to halt it as a console. 

---------

So closing this incident; there is already the report

https://issues.apache.org/bugzilla/show_bug.cgi?id=25484

for tracking how to close the "console mode" httpd.exe with -k stop.

And for continued dialog on what ^C does to a detached daemon, we can carry
on that discussion, if necessary, on the dev@ list.