cvs commit: modperl-docs/src/docs/2.0/user Changes.pod
stas2003/11/14 21:42:22 Modified:src/docs/2.0/user/troubleshooting troubleshooting.pod src/docs/2.0/user Changes.pod Log: A new troubleshooting section on how to resolve "undefined symbol" problems Submitted by: Matisse Enzer <[EMAIL PROTECTED]> Revision ChangesPath 1.15 +155 -1 modperl-docs/src/docs/2.0/user/troubleshooting/troubleshooting.pod Index: troubleshooting.pod === RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/troubleshooting/troubleshooting.pod,v retrieving revision 1.14 retrieving revision 1.15 diff -u -u -r1.14 -r1.15 --- troubleshooting.pod 14 Oct 2003 04:09:59 - 1.14 +++ troubleshooting.pod 15 Nov 2003 05:42:21 - 1.15 @@ -169,6 +169,155 @@ http://httpd.apache.org/docs-2.0/faq/error.html#error.sendfile +=head2 undefined symbol: apr_table_compress + +After a successful mod_perl build, sometimes during the startup or a +runtime you'd get an "undefined symbol: foo" error. The following is +one possible scenario to encounter this problem and possible ways to +resolve it. + +Let's say you ran mod_perl's test suite: + + % make test + +and got errors, and you looked in the F file +(F) and saw one or more "undefined symbol" errors, +e.g. + + % undefined symbol: apr_table_compress + +=over + +=item Step 1 + +From the source directory (same place you ran "make test") run: + + % ldd blib/arch/auto/APR/APR.so | grep apr- + +META: ldd is not available on all platforms, e.g. not on Darwin/OS X + +You you should get a full path, for example: + + libapr-0.so.0 => /usr/local/apache2/lib/libapr-0.so.0 (0x40003000) + +or + + libapr-0.so.0 => /some/path/to/apache/lib/libapr-0.so.0 (0x40003000) + +or something like that. It's that full path to libapr-0.so.0 that you +want. + + +=item Step 2 + +Do: + + % nm /path/to/your/libapr-0.so.0 | grep table_compress + +for example: + + % nm /usr/local/apache2/lib/libapr-0.so.0 | grep table_compress + +You should get something like this: + + d010 T apr_table_compress + +Note that the "grep table_compress" is only an example, the exact +string you are looking for is the name of the "undefined symbol" from +the error_log. So, if you got "undefined symbol: apr_holy_grail" then +you would do + + % nm /usr/local/apache2/lib/libapr-0.so.0 | grep holy_grail + +=item Step 3 + +Now, let's see what shared libraries your apache binary has. So, if in +step 1 you got F then you will +do: + + % ldd /usr/local/apache2/bin/httpd + +if in step 1 you got F then you do: + + % ldd /foo/bar/apache/bin/httpd + +The output should look something like this: + + libssl.so.2 => /lib/libssl.so.2 (0x40023000) + libcrypto.so.2 => /lib/libcrypto.so.2 (0x40054000) + libaprutil-0.so.0 => /usr/local/apache2/lib/libaprutil-0.so.0 (0x40128000) + libgdbm.so.2 => /usr/lib/libgdbm.so.2 (0x4013c000) + libdb-4.0.so => /lib/libdb-4.0.so (0x40143000) + libexpat.so.0 => /usr/lib/libexpat.so.0 (0x401eb000) + libapr-0.so.0 => /usr/local/apache2/lib/libapr-0.so.0 (0x4020b000) + librt.so.1 => /lib/librt.so.1 (0x40228000) + libm.so.6 => /lib/i686/libm.so.6 (0x4023a000) + libcrypt.so.1 => /lib/libcrypt.so.1 (0x4025c000) + libnsl.so.1 => /lib/libnsl.so.1 (0x40289000) + libdl.so.2 => /lib/libdl.so.2 (0x4029f000) + libpthread.so.0 => /lib/i686/libpthread.so.0 (0x402a2000) + libc.so.6 => /lib/i686/libc.so.6 (0x4200) + /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x4000) + +Those are name =E value pairs showing the shared libraries used by +the C binary. + +Take note of the value for F and compare it to what you +got in step 1. They should be the same, if not, then mod_perl was +compiled pointing to the wrong Apache installation. You should run +"make clean" and then + + % perl Makefile.pl MP_APACHE_CONFIG=/path/to/apache/bin/apr-config + +using the correct path for the Apache installation. + +=item Step 4 + +You should also search for extra copies of F. If you +find one in I or I that will explain the +problem. Most likely you have an old pre-installed apr package which +gets loaded before the copy you found in step 1. + +On most Linux (and Mac OS X) machines you can do a fast search with: + + % locate libapr-0.so.0 + +which searches a database of files on your machine. The "locate" +database isn't always up-to-date so a slower, more comprehensive +search can be run (as root if possible): + + % find / -name "libapr-0.so.0*" + +or + + % find /usr/local -name "libapr-0.so.0*" + +You might get output like this: + + /usr/local/apache2.0.47/lib/libapr-0.so.0.9.4 + /usr/local/apache2.0.47/lib/libapr-0.so.0 + /usr/local/apache2.0.45/lib/libapr-0.so.0.9.
cvs commit: modperl-docs/src/docs/general Changes.pod
stas2003/11/14 22:12:21 Modified:src/docs/1.0/guide porting.pod Changes.pod src/docs/general/perl_reference perl_reference.pod src/docs/general Changes.pod Log: modernize coding techniques sections in porting.pod and perl_reference Submitted by: Brian McCauley <[EMAIL PROTECTED]> Revision ChangesPath 1.20 +56 -42modperl-docs/src/docs/1.0/guide/porting.pod Index: porting.pod === RCS file: /home/cvs/modperl-docs/src/docs/1.0/guide/porting.pod,v retrieving revision 1.19 retrieving revision 1.20 diff -u -u -r1.19 -r1.20 --- porting.pod 15 Jul 2003 11:06:02 - 1.19 +++ porting.pod 15 Nov 2003 06:12:21 - 1.20 @@ -88,7 +88,7 @@ print "Content-type: text/plain\r\n\r\n"; - my $counter = 0; + my $counter = 0; # Explicit initialization technically redundant for (1..5) { increment_counter(); @@ -195,8 +195,8 @@ print "Content-type: text/plain\r\n\r\n"; -my $counter = 0; - +my $counter = 0; # Explicit initialization technically redundant + for (1..5) { increment_counter(); } @@ -228,51 +228,65 @@ It's important to understand that the I effect happens only with code that C wraps with a -declaration of the C subroutine. If you put your code into a -library or module, which the main script require()'s or use()'s, this -effect doesn't occur. - -For example if we move the code from the script into the subroutine -I, place the subroutines into the I file, save it in -the same directory as the script itself and require() it, there will -be no problem at all. (Don't forget the C<1;> at the end of the -library or the require() might fail.) - - mylib.pl: - - - my $counter; - sub run{ -print "Content-type: text/plain\r\n\r\n"; -$counter = 0; -for (1..5) { - increment_counter(); -} +declaration of the C subroutine. If you put all your code +into modules, which the main script Cs, this effect doesn't +occur. + +Do not use Perl4-style libraries. Subroutines in such libraries will +only be available to the first script in any given interpreter thread +to C a library of any given name. This can lead to +confusing sporadic failures. + +The easiest and the fastest way to solve the nested subroutines +problem is to switch every lexically scoped variable foe which you get +the warning for to a package variable. The C subroutines are +never called re-entrantly and each resides in a package to itself. +Most of the usual disadvantates of package scoped variables are, +therefore, not a concern. Note, however, that whereas explicit +initialization is not always necessary for lexical variables it is +usually necessary for these package variables as they persist in +subsequent executions of the handler and unlike lexical variables, +don't get automatically destroyed at the end of each handler. + + + counter.pl: + -- + #!/usr/bin/perl -w + use strict; + + print "Content-type: text/plain\r\n\r\n"; + + # In Perl <5.6 our() did not exist, so: + # use vars qw($counter); + our $counter = 0; # Explicit initialization now necessary + + for (1..5) { +increment_counter(); } + sub increment_counter{ $counter++; print "Counter is equal to $counter !\r\n"; } - 1; - - counter.pl: - -- - use strict; - require "./mylib.pl"; - run(); -This solution provides the easiest and the fastest way to solve the -nested subroutines problem, since all you have to do is to move the -code into a separate file, by first wrapping the initial code into -some function that you later will call from the script and keeping the -lexically scoped variables that could cause the problem out of this -function. - -But as a general rule of thumb, unless the script is very short, I -tend to write all the code in external libraries, and to have only a -few lines in the main script. Generally the main script simply calls -the main function of my library. Usually I call it C or -C. I don't worry about nested subroutine effects anymore -(unless I create them myself :). +If the variable contains a reference it may hold onto lots of +unecessary memory (or worse) if the reference is left to hang about +until the next call to the same handler. For such variables you +should use C so that the value is removed when the C +subroutine exits. + + my $query = CGI->new; + +becomes: + + local our $query = CGI->new; + +All this is very interesting but as a general rule of thumb, unless +the script is very short, I tend to write all the code in external +libraries, and to have only a few lines in the main script. G