At 08:07 PM 3/29/2003, Jeff Trawick wrote:
Maybe there is a Solaris patch for this :) It seems really sucky for exec to have a failure point after close-for-exec files are closed and after signal handling is reset.
No... look at what we do in apr_proc_child_create ... we are the ones closing all of the handles that we need in invoking ap_log_error()! Can't blame the OS for this one :-)
oh, in apr_proc_create()->apr_pool_cleanup_for_exec() I guess
yeah, I can see the normal error log file descriptor getting cleaned up by apr_pool_cleanup_for_exec()
but something I forgot about: mod_cgid sets r->server->error_log descriptor to STDERR after accepting a new CGI request:
while (!daemon_should_exit) {
int errfileno = STDERR_FILENO;
...
apr_os_file_put(&r->server->error_log, &errfileno, 0, r->pool);
apr_os_file_put(&inout, &sd2, 0, r->pool);and when I hit cgid_child_errfn() due to an exec failure, stderr is where it will try to write
(gdb) p *r->server->error_log
$6 = {pool = 0x813fba0, filedes = 2, fname = 0x0, flags = 2048, eof_hit = 0,
is_pipe = 0, timeout = -1, buffered = 0, blocking = BLK_UNKNOWN,
ungetchar = -1, buffer = 0x0, bufpos = 0, dataRead = 0, direction = 0,
filePtr = 0, thlock = 0x0}oh darn, I took a wild branch... this doesn't have anything to do with cgid_child_errfn at all... it is this code, isn't it??? (look at Sander's minimal traceback (which would be much better with a -g build and line numbers!!!))
rc = ap_os_create_privileged_process(r, procnew, argv0, argv,
(const char * const *)env,
procattr, ptrans); if (rc != APR_SUCCESS) {
/* Bad things happened. Everyone should have cleaned up. */
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, rc, r,
"couldn't create child process: %d: %s", rc,
apr_filename_of_pathname(r->filename));when I force rc != APR_SUCCESS on Linux, I get a segfault... the problem is that ap_log_rerror() references r->headers_in, which wasn't replicated in the daemon... the attached patch works around that in the same manner as cgid_child_errfn()
no theory here for why I get segfault and you get SIGPIPE from writing to a closed descriptor; it certainly is an indication that we are talking about different problems, but I've been up and down the cgid_child_errfn() path and can't make it fail
alternatively, this code could just do ap_log_error(..., main_server, ...)
also, shouldn't the APLOG_TOCLIENT flag get zapped since it doesn't apply to ap_log_error()?
recap: I find different code that is problematic I can make that different code fail, but with different symptom from you please try the patch to see if your symptom changes or goes away
Index: modules/generators/mod_cgid.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/generators/mod_cgid.c,v
retrieving revision 1.145.2.3
diff -u -r1.145.2.3 mod_cgid.c
--- modules/generators/mod_cgid.c 27 Feb 2003 12:33:08 -0000 1.145.2.3
+++ modules/generators/mod_cgid.c 30 Mar 2003 13:26:59 -0000
@@ -757,10 +757,13 @@
procattr, ptrans);
if (rc != APR_SUCCESS) {
- /* Bad things happened. Everyone should have cleaned up. */
- ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, rc, r,
- "couldn't create child process: %d: %s", rc,
- apr_filename_of_pathname(r->filename));
+ /* Bad things happened. Everyone should have cleaned up.
+ * ap_log_rerror() won't work because the header table used by
+ * ap_log_rerror() hasn't been replicated in the phony r
+ */
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, rc, r->server,
+ "couldn't create child process: %d: %s", rc,
+ apr_filename_of_pathname(r->filename));
}
else {
apr_hash_set(script_hash, &cgid_req.conn_id,
sizeof(cgid_req.conn_id),
