Stas Bekman wrote:
>> When spawn_proc_prog() is called I get a segfault in strrchr when
>> modperl_spawn_proc_prog calls ap_make_dirstr_parent, which then
calls
>> strrchr. Unfortunately, my Perl 5.8 and Apache are not compiled with
>> debugging on so I'm recompiling all now. More later....
>
> Ouch, a simple test case would be useful and hopefully I'll be able
to
> reproduce it. As I mentioned there are only some very basic tests in
> t/apache/subprocess.t & t/response/TestApache/subprocess.pm, if you
can add
> more tests that would be great.
Okay - test case and resulting stack traces below. My Apache executible
only includes a few modules as I'm trying to wring the last ounce of
performance out of it, so it fails most of the canned test cases. The
modules I have are: core.c mod_log_config.c mod_ssl.c worker.c
http_core.c mod_status.c mod_cgid.c mod_alias.c and mod_so.c
>
>> Understand re: cleanup_for_exec
>>
>> I read the Avoiding Zombies section and $SIG{CHLD} = 'IGNORE' didn't
work
>> for me. I realize that I didn't try the waitpid() example after the
fork.
>
> I suppose this varies from OS to OS :(
>
> Was your suggestion different from the one in the guide?
Yes - it's the only one I could get to work w/ Solaris 8. It seems to
be the
POSIX options that do it. Also, my version will find any child and
reap if
ready, whereas the guide will only collect the specified pid. I'm
doing a fork
and exec, then the exec'd process hangs around for 1-10 minutes so I
have
to be able to reap anything that needs reaping.
Here is my simple test case:
package RELPERL::MyFork;
use strict;
use warnings;
use Apache::SubProcess ();
sub handler {
my $r = shift;
$r->content_type('text/plain');
my($cmd)="/bin/ls";
my(@args)= qw(/etc /);
my($out_fh) =
Apache::SubProcess::spawn_proc_prog($r,$cmd,[EMAIL PROTECTED]);
my($appout) = &read_data($out_fh);
return Apache::OK;
}
sub read_data
{
my($fh)[EMAIL PROTECTED];
my($data);
$data = ""
return defined $data ? $data : '';
}
1;
I ran this test case against Apache 2.0.47 / Perl 5.8.0 / modperl
1.99.10-dev
(the 3 PM ish 20030923 version) all compiled under GCC 3.3 on Sol 2.8
with
CFLAGS of -g -O0.
Here's the stack trace. Note that r->filename is null when
ap_make_dirstr_parent()
is called. Also, *command is "/", which doesn't seem right, but ***argv of "/"
seems okay.
When we get to line 51 in Apache__SubProcess.h - if
(FAILED(apr_procattr_create(&procattr, p)) || ....
a next or step produces a segfault.
Breakpoint 1, modperl_spawn_proc_prog (my_perl=0x194b60, r=0x30fdc88,
command=0x2a826c0 "/bin/ls", argv=0xfdd09250, script_in=0xfdd09260,
script_out=0xfdd0925c, script_err=0xfdd09258)
at
/export/debugger-O0/modperl-2.0/xs/Apache/SubProcess/Apache__SubProcess.h:39
(gdb) p *r
$9 = {pool = 0x30fdc50, connection = 0x30f3d48, server = 0x115260, next
= 0x0,
prev = 0x0, main = 0x0, the_request = 0x30fea90 "GET /test/myfork
HTTP/1.1",
assbackwards = 0, proxyreq = 0, header_only = 0,
protocol = 0x30feb18 "HTTP/1.1", proto_num = 1001,
hostname = 0x30ff258 "sfivrapp02.telebank.foo.com",
request_time = 1064437591906258, status_line = 0x0, status = 200,
method = 0x30feae0 "GET", method_number = 0, allowed = 0,
allowed_xmethods = 0x0, allowed_methods = 0x30fde10, sent_bodyct = 0,
bytes_sent = 0, mtime = 0, chunked = 0, range = 0x0, clength = 0,
remaining = 0, read_length = 0, read_body = 0, read_chunked = 0,
expecting_100 = 0, headers_in = 0x30fde40, headers_out = 0x30fe2d0,
err_headers_out = 0x30fe478, subprocess_env = 0x30fe088, notes =
0x30fe5d0,
content_type = 0x3101dc8 "text/plain", handler = 0x14b5a0 "modperl",
content_encoding = 0x0, content_languages = 0x0, vlist_validator =
0x0,
user = 0x0, ap_auth_type = 0x0, no_cache = 0, no_local_copy = 0,
unparsed_uri = 0x30feaf8 "/test/myfork", uri = 0x30feb08
"/test/myfork",
filename = 0x0, canonical_filename = 0x0, path_info = 0x0, args =
0x0,
finfo = {pool = 0x0, valid = 0, protection = 0, filetype =
APR_NOFILE,
user = 0, group = 0, inode = 0, device = 0, nlink = 0, size = 0,
csize = 0, atime = 0, mtime = 0, ctime = 0, fname = 0x0, name =
0x0,
filehand = 0x0}, parsed_uri = {scheme = 0x0, hostinfo = 0x0, user =
0x0,
password = 0x0, hostname = 0x0, port_str = 0x30ff288 "55555",
path = 0x30feb08 "/test/myfork", query = 0x0, fragment = 0x0,
hostent = 0x0, port = 55555, is_initialized = 1, dns_looked_up = 0,
dns_resolved = 0}, used_path_info = 2, per_dir_config = 0x30ff308,
request_config = 0x30fe728, htaccess = 0x0, output_filters =
0x30fea20,
input_filters = 0x30fe888, proto_output_filters = 0x30fea20,
proto_input_filters = 0x30fe888, eos_sent = 0}
(gdb) p *r->pool
$10 = {parent = 0x30f3c30, child = 0x0, sibling = 0x0, ref = 0x30f3c34,
cleanups = 0x30ff9b8, allocator = 0x2eab8e8, subprocesses = 0x0,
abort_fn = 0, user_data = 0x30ff8f8, tag = 0x0, active = 0x30ffd98,
self = 0x30fdc38, self_first_avail = 0x30fdc88 "\003\017P\003\017=H"}
(gdb) p *command
$11 = 47 '/'
(gdb) p ***argv
$12 = 47 '/'
(gdb) p **script_in
$13 = {pool = 0x1c5bae4, filedes = 2126160, fname = 0x3015130 "",
flags = 29735640, eof_hit = 29736148, is_pipe = 51088576,
timeout = 42949672992, buffered = 29736680, blocking = 71, ungetchar
= buffer,
128", bufpos = 0, dataRead = 0, direction = 128,
filePtr = 51088440, thlock = 0x30b8c40}
(gdb) p **script_out
Cannot access memory at address 0x0
(gdb) p **script_err
Cannot access memory at address 0x0
(gdb) p e_info
$14 = {in_pipe = 51371088, out_pipe = 51387864, err_pipe = 1657696,
cmd_type = 51379608}
(gdb) p *p
$15 = {parent = 0x2a826c0, child = 0x2cfa798, sibling = 0x2e76200, ref
= 0x0,
cleanups = 0x0, allocator = 0x0, subprocesses = 0x0, abort_fn = 0,
user_data = 0x0, tag = 0x0, active = 0x0, self = 0x0,
self_first_avail = 0x0}
(gdb) p *env
Cannot access memory at address 0x0
(gdb) p *procattr
Cannot access memory at address 0x0
(gdb) p *procnew
Cannot access memory at address 0x0
(gdb) n
(gdb)
(gdb)
(gdb)
(gdb)
(gdb) p r->main
$16 = (request_rec *) 0x0
(gdb) n
(gdb)
(gdb)
(gdb) p env
$17 = (const char * const*) 0x3101de8
(gdb) p *env
$18 = 0x3101df8 "TZ=US/Pacific"
(gdb) p procattr
$19 = (apr_procattr_t *) 0x0
(gdb) p &procattr
$20 = (apr_procattr_t **) 0xfdd09194
(gdb) p apr_procattr_t
Attempt to use a type name as an _expression_
(gdb) p e_info.in_pipe
$21 = 4
(gdb) p e_info.out_pipe
$22 = 4
(gdb) p e_info.err_pipe
$23 = 4
(gdb) p r->pool
$24 = (apr_pool_t *) 0x30fdc50
(gdb) p r->filename
$25 = 0x0
(gdb) p e_info.cmd_type
$26 = APR_PROGRAM
(gdb) ***** AT Apache__SubProcess.h:51 - next or step here segfaults
*****
Hope this helps.
Thanks,
Scot