You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Alex Shnitman <al...@livelinx.com> on 2000/07/13 16:07:46 UTC

Weird behaviour

Hi,

I've come across some totally weird behaviour of <Perl> sections. I'm
enclosing a minimalistic httpd.conf that shows it. In order to test
it, create a directory called "zz", put it there, cd to that
directory, and run /usr/sbin/apache -f `pwd`/httpd.conf .

What it tries to do is get the current working directory (via
POSIX::getcwd), and then look up the port to bind to in a hash,
according to this directory. If the name of the directory comes from
getcwd, it's printed correctly by the print statements (!), but then
Apache doesn't recognize it and tries to bind to port 80 anyway!
However, if you assign the value to the variable manually (there's a
commented line that does it, uncomment it) it works perfectly. It
prints the same output, but it binds to the correct port.

Can anyone please help me to figure this out? It looks like some very
subtle bug. If you try to reproduce it but can't, please tell me
too. Maybe it's something weird with my configuration.

I'm using Apache 1.3.12 and mod_perl 1.24.

Thanks a lot in advance!


-- 
Alex Shnitman <al...@livelinx.com>
LiveLinx Extensible Solutions Ltd.

Re: Weird behaviour

Posted by Alex Shnitman <al...@livelinx.com>.
On Thu, Jul 13, 2000 at 09:47:59PM +0000, G.W. Haywood wrote:

> > httpd.conf
> 
> I see that %port is a lexical but $Port isn't.  Is that a clue?

I have no idea. Is it?


-- 
Alex Shnitman <al...@livelinx.com>
LiveLinx Extensible Solutions Ltd.

Re: Weird behaviour

Posted by Rick Myers <ri...@sumthin.nu>.
On Jul 20, 2000 at 11:16:47 +0300, Alex Shnitman twiddled the keys to say:
> On Wed, Jul 19, 2000 at 10:24:24PM -0400, Rick Myers wrote:
> 
> > After fooling with this for several hours I've finally come to the
> > conclusion that this is probably an Apache "problem".
> > 
> > [...]
> > 
> > *whew*
> 
> Wow, MAN! Thank you SO much! It indeed worked!
> 
> A couple of questions remain -- why is the config file parsed twice?

Honestly, I don't know. I could throw out a couple theories here, but
they would be mostly guesswork. In fact, I didn't know myself that there
was a double parse at initial startup. I was aware of that sort of thing
on restarts though.

> Also, what about this observation:
> 
> > > > > Another interesting thing about this issue: if I assign
> > > > > $port{$portname} + 1 to $Port, and not just $port{$portname}, it
> > > > > works! If I ever try to return $Port to the needed value, e.g. using
> > > > > the -- operator, it doesn't work again. This completely stumps me. I
> > > > > tried just about any trick you can think of to get the value from
> > > > > $port{$portname} to $Port, but I can't -- if I add to it or substract
> > > > > from it, it's fine, but if it somehow gets back to the original value,
> > > > > in any way, it doesn't work again.

I went down that path myself since you'd already suggested it. What I
ended up with was indeed a working server, but not on the port you'd
think. For instance, if the desired port was 1885 and I added one to it,
I should've been able to connect to 1886. Instead, what I really had was
a server listening on port 1. When I tried adding 4 to the port I ended
up with a server listening on port 4.

What was really going on was that the second time through the <Perl>
section, POSIX::getcwd was returning `/'. After s!.*/!! you end up with
`', which when used to index into %port returns undef. Now, if you add 1
to that the result is 1, so the server starts and listens on port 1. If
you don't add anything, undef is passed on to Apache, which I guess
assumes you really meant the standard 80. Of course, that promptly barfs
because there's already another server listening there.

Rick Myers                            rik@sumthin.nu
----------------------------------------------------
The Feynman Problem       1) Write down the problem.
Solving Algorithm         2) Think real hard.
                          3) Write down the answer.

Re: Weird behaviour

Posted by Alex Shnitman <al...@livelinx.com>.
On Wed, Jul 19, 2000 at 10:24:24PM -0400, Rick Myers wrote:

> After fooling with this for several hours I've finally come to the
> conclusion that this is probably an Apache "problem".
> 
> [...]
> 
> *whew*

Wow, MAN! Thank you SO much! It indeed worked!

A couple of questions remain -- why is the config file parsed twice?
Also, what about this observation:

> > > > Another interesting thing about this issue: if I assign
> > > > $port{$portname} + 1 to $Port, and not just $port{$portname}, it
> > > > works! If I ever try to return $Port to the needed value, e.g. using
> > > > the -- operator, it doesn't work again. This completely stumps me. I
> > > > tried just about any trick you can think of to get the value from
> > > > $port{$portname} to $Port, but I can't -- if I add to it or substract
> > > > from it, it's fine, but if it somehow gets back to the original value,
> > > > in any way, it doesn't work again.

Now it's just academic interest, because it works after all, but I'm
still curious. (Please don't fool with it for several hours! ;-)


Thanks again!

-- 
Alex Shnitman <al...@livelinx.com>
LiveLinx Extensible Solutions Ltd.

Re: Weird behaviour

Posted by Rick Myers <ri...@sumthin.nu>.
On Jul 19, 2000 at 10:09:36 +0300, Alex Shnitman twiddled the keys to say:
> On Tue, Jul 18, 2000 at 11:30:44PM -0400, Rick Myers wrote:
> 
> > > Another interesting thing about this issue: if I assign
> > > $port{$portname} + 1 to $Port, and not just $port{$portname}, it
> > > works! If I ever try to return $Port to the needed value, e.g. using
> > > the -- operator, it doesn't work again. This completely stumps me. I
> > > tried just about any trick you can think of to get the value from
> > > $port{$portname} to $Port, but I can't -- if I add to it or substract
> > > from it, it's fine, but if it somehow gets back to the original value,
> > > in any way, it doesn't work again.
> > > 
> > > Does that give any new ideas as to the source of this issue?
> > 
> > Yes. The source of the issue is that you sent your ErrorLog to
> > /dev/null. Send it somewhere else where you can read it and you should
> > find the error in short order.
> 
> That's what I do in my configuration file -- I just trimmed it down to
> show just the code that matters in the sample that I sent to the list.
> 
> Here's the error I get in the error log:
> [Wed Jul 19 10:07:14 2000] [crit] (13)Permission denied: make_sock: could not bind to port 80
> It couldn't bind to port 80 because another web server is running
> there. This means that it didn't recognize the $Port setting,
> although printing $Port from within the config file prints 8010
> properly. That's precisely the problem.

After fooling with this for several hours I've finally come to the
conclusion that this is probably an Apache "problem".

The quickest way to illustrate it is trying this <Perl> section...

   <Perl>
   my %port = ( zz => 8014 );
   warn "PORTHASH: $port\n";
   
   use POSIX ();
   my $portname = POSIX::getcwd();
   chomp $portname;
   warn "PORTNAME1: '$portname'\n";
   $portname =~ s:.*/::;
   warn "PORTNAME2: '$portname'\n";
   
   $Port = $port{$portname};
   warn "PORT: '$Port'\n";
   my $ppid = getppid;
   warn "PPID: $ppid\n";
   </Perl>

Now, try running your server as before, but make sure you have access to
the ErrorLog file. You'll notice that several of the warn()'s generate
completely different output in the error_log than they do on your shell
screen.

The first significant difference is that PORTNAME1 points to `/home/zz'
(or wherever you started httpd from) in your shell, while in the
error_log it points to `/'. I'd almost bet money that the conf file is
parsed the first time under your shell, then again after Apache has
disassociated itself, thus showing you seemingly valid output on the
shell.

If you then grep through the Apache source you'll find this in
src/main/http_main.c...

   static void detach(void)
   {
   #if !defined(WIN32) && !defined(NETWARE)
       int x;
   
       chdir("/");

Bingo!

Now the question is how to pass the proper directory name to mod_perl's
<Perl> sections. The answer lies subtly tucked away on p. 423 of the
Eagle book. Just add a PerlPassEnv to your conf file...

   PerlPassEnv PWD

Then use $ENV{PWD} instead of POSIX::getcwd() and you should be all set.

*whew*

Rick Myers                            rik@sumthin.nu
----------------------------------------------------
The Feynman Problem       1) Write down the problem.
Solving Algorithm         2) Think real hard.
                          3) Write down the answer.

Re: Weird behaviour

Posted by Alex Shnitman <al...@livelinx.com>.
On Tue, Jul 18, 2000 at 11:30:44PM -0400, Rick Myers wrote:

> > Another interesting thing about this issue: if I assign
> > $port{$portname} + 1 to $Port, and not just $port{$portname}, it
> > works! If I ever try to return $Port to the needed value, e.g. using
> > the -- operator, it doesn't work again. This completely stumps me. I
> > tried just about any trick you can think of to get the value from
> > $port{$portname} to $Port, but I can't -- if I add to it or substract
> > from it, it's fine, but if it somehow gets back to the original value,
> > in any way, it doesn't work again.
> > 
> > Does that give any new ideas as to the source of this issue?
> 
> Yes. The source of the issue is that you sent your ErrorLog to
> /dev/null. Send it somewhere else where you can read it and you should
> find the error in short order.

That's what I do in my configuration file -- I just trimmed it down to
show just the code that matters in the sample that I sent to the list.

Here's the error I get in the error log:
[Wed Jul 19 10:07:14 2000] [crit] (13)Permission denied: make_sock: could not bind to port 80
It couldn't bind to port 80 because another web server is running
there. This means that it didn't recognize the $Port setting,
although printing $Port from within the config file prints 8010
properly. That's precisely the problem.


-- 
Alex Shnitman <al...@livelinx.com>
LiveLinx Extensible Solutions Ltd.

Re: Weird behaviour

Posted by Rick Myers <ri...@sumthin.nu>.
On Jul 18, 2000 at 22:34:05 +0300, Alex Shnitman twiddled the keys to say:
> Another interesting thing about this issue: if I assign
> $port{$portname} + 1 to $Port, and not just $port{$portname}, it
> works! If I ever try to return $Port to the needed value, e.g. using
> the -- operator, it doesn't work again. This completely stumps me. I
> tried just about any trick you can think of to get the value from
> $port{$portname} to $Port, but I can't -- if I add to it or substract
> from it, it's fine, but if it somehow gets back to the original value,
> in any way, it doesn't work again.
> 
> Does that give any new ideas as to the source of this issue?

Yes. The source of the issue is that you sent your ErrorLog to
/dev/null. Send it somewhere else where you can read it and you should
find the error in short order.

Rick Myers                            rik@sumthin.nu
----------------------------------------------------
The Feynman Problem       1) Write down the problem.
Solving Algorithm         2) Think real hard.
                          3) Write down the answer.

Re: Weird behaviour

Posted by Alex Shnitman <al...@livelinx.com>.
Another interesting thing about this issue: if I assign
$port{$portname} + 1 to $Port, and not just $port{$portname}, it
works! If I ever try to return $Port to the needed value, e.g. using
the -- operator, it doesn't work again. This completely stumps me. I
tried just about any trick you can think of to get the value from
$port{$portname} to $Port, but I can't -- if I add to it or substract
from it, it's fine, but if it somehow gets back to the original value,
in any way, it doesn't work again.

Does that give any new ideas as to the source of this issue?


-- 
Alex Shnitman <al...@livelinx.com>
LiveLinx Extensible Solutions Ltd.

Re: Weird behaviour

Posted by Alex Shnitman <al...@livelinx.com>.
So, is this a real bug? Can someone confirm this?

-- 
Alex Shnitman <al...@livelinx.com>
LiveLinx Extensible Solutions Ltd.

Re: Weird behaviour

Posted by "G.W. Haywood" <ge...@www.jubileegroup.co.uk>.
Hi there,

On Sun, 16 Jul 2000, Ask Bjoern Hansen wrote:

> On Thu, 13 Jul 2000, G.W. Haywood wrote:
> 
> > > httpd.conf
> > 
> > I see that %port is a lexical but $Port isn't.  Is that a clue?
> 
> I don't think so. Except if mod_perl does some very weird stuff they
> should be all separate.

Yeah, well I didn't really think so either, but sometimes a shot in
the dark pulls a cat out of the bag.  (Or something:)

73,
Ged.


Re: Weird behaviour

Posted by Ask Bjoern Hansen <as...@valueclick.com>.
On Thu, 13 Jul 2000, G.W. Haywood wrote:

> > httpd.conf
> 
> I see that %port is a lexical but $Port isn't.  Is that a clue?

I don't think so. Except if mod_perl does some very weird stuff they
should be all separate.

try:

$foo = "foo";   # no different with or without my
$Foo = "Foo";
%foo = (beep => "hash foo");

print "\$foo: $foo\n";
print "\$Foo: $Foo\n";
print "\$foo{beep}: $foo{beep}\n";


 - ask

-- 
ask bjoern hansen - <http://www.netcetera.dk/~ask/>
more than 70M impressions per day, <http://valueclick.com>


Re: Weird behaviour

Posted by "G.W. Haywood" <ge...@jubileegroup.co.uk>.
Hi there,

On Thu, 13 Jul 2000, Alex Shnitman wrote:

> httpd.conf

I see that %port is a lexical but $Port isn't.  Is that a clue?

73,
Ged.



Re: Weird behaviour

Posted by Alex Shnitman <al...@livelinx.com>.
Of course, I forgot to attach the httpd.conf itself. Here it
is. Sorry.


-- 
Alex Shnitman <al...@livelinx.com>
LiveLinx Extensible Solutions Ltd.