randygalbraith has asked for the wisdom of the Perl Monks concerning the following question:

Hi PerlMonks,

The wisdom I'm seeking relates to Perl DynaLoader on IBM AIX. Specifically in regards to the Tuxedo-2.08 module on IBM AIX. This module will allow me to create a Perl program to call a service within a Tuxedo domain. Tuxedo is Oracle's middleware for C, originally from BEA.

Here are my details:
$ uname -a AIX hostname 1 6 00CBD3124C00 $ gcc --version gcc (GCC) 4.6.3 Copyright (C) 2011 Free Software Foundation, Inc. $ perl --version This is perl 5, version 16, subversion 2 (v5.16.2) built for aix-threa +d-multi-64int $ echo $TUXDIR /opt/tuxedo/11.1_32

An initial attempt to compile the module fails in a way we've seen before, let me demo this... With AIX 6.1, gcc 4.6.3, Perl 5.16.2 and Tuxedo 11.1 I do this...

$ tar zxvf Tuxedo-2.08.tar.gz Tuxedo-2.08/ Tuxedo-2.08/testflds <snip> $ cd Tuxedo-2.08/ $ perl Makefile.PL Checking if your kit is complete... Looks good Writing Makefile for Tuxedo Writing MYMETA.yml and MYMETA.json $ make --version GNU Make 4.0 Built for powerpc-ibm-aix6.1.0.0 $ make test cp tpadm.pm blib/lib/tpadm.pm cp genubbconfig.pl blib/lib/genubbconfig.pl <snip> CC="gcc -maix32 -L/usr/local/lib -L/path/to/perl-5.16.2/powerpc-AIX6.1 +/lib/CORE"; export CC; /opt/tuxedo/11.1_32/bin/buildserver -o PERLSVR + -s ":PERL" -f "blib/arch/auto/Tuxedo/Tuxedo.so" -f "-Xlinker -bE:/pa +th/to/perl-5.16.2/powerpc-AIX6.1/lib/CORE/perl.exp -Wl,-brtl -Wl,-bd +ynamic -Wl,-b32 -Wl,-bmaxdata:0x80000000 -lperl -lbind -lnsl -ldl -l +ld -lm -lcrypt -lpthreads -lc" gcc: error: unrecognized option '-brtl' gcc: error: unrecognized option '-qstaticinline' gcc: error: unrecognized option '-qrtti=all' gcc: error: unrecognized option '-brtl' gcc: error: unrecognized option '-qstaticinline'

The problem here is "buildserver" issues a gcc command that includes these -b and -q linker options. Older versions of gcc probably did not mind this, but it does now. Fortunately, we've fixed this in our environment by writing a script that runs buildserver to extract the compile command then using sed edit out these offending options. If I do that I can get past these gcc errors. Admittedly, this approach may be where I go off the rails, however I can report our custom script works for building Tuxedo server processes for our development group on AIX many times a day.

So.. lets do this again, but now with a replacement for buildserver...

$ rm -rf Tuxedo-2.08 $ tar zxvf Tuxedo-2.08.tar.gz $ cp Makefile.PL Tuxedo-2.08/. $ cd Tuxedo-2.08/ $ perl Makefile.PL perl Makefile.PL Checking if your kit is complete... Looks good Writing Makefile for Tuxedo Writing MYMETA.yml and MYMETA.json

My custom Makefile.PL creates a script called aix-buildserver, so when we run...

$ make test <snip> CC="gcc -maix32 -L/usr/local/lib -L/path/to/perl-5.16.2/powerpc-AIX6.1 +/lib/CORE"; export CC; ./aix-buildserver -o PERLSVR -s ":PERL" -f "bl +ib/arch/auto/Tuxedo/Tuxedo.so" -f "-Xlinker -bE:/path/to/perl-5.16.2/ +powerpc-AIX6.1/lib/CORE/perl.exp -Wl,-brtl -Wl,-bdynamic -Wl,-b32 -W +l,-bmaxdata:0x80000000 -lperl -lbind -lnsl -ldl -lld -lm -lcrypt -lp +threads -lc"

I have the script report the gcc command it built as follows...

COMPILE_CMD=gcc -maix32 -L/usr/local/lib -L/path/to/perl-5.16.2/powerp +c-AIX6.1/lib/CORE -I/opt/tuxedo/11.1_32/include -o PERLSVR BS-1d301fe +.c -L/opt/tuxedo/11.1_32/lib blib/arch/auto/Tuxedo/Tuxedo.so -Xlinker + -bE:/path/to/perl-5.16.2/powerpc-AIX6.1/lib/CORE/perl.exp -Wl,-bdyna +mic -Wl,-b32 -Wl,-bmaxdata:0x80000000 -lperl -lbind -lnsl -ldl -lld - +lm -lcrypt -lpthreads -lc -ltux -lbuft -lfml -lfml32 -lengine -lpthre +ad

Running $COMPILE_CMD, works without problem. In fact the PERLSVR executable can be run. But look what happens when Perl attempts to load Tuxedo.so:

PERL_DL_NONLAZY=1 /path/to/powerpc-AIX6.1/bin/perl "-Iblib/lib" "-Ibli +b/arch" test.pl 1..1 Can't load 'blib/arch/auto/Tuxedo/Tuxedo.so' for module Tuxedo: rtld: +0712-001 Symbol tptypes was referenced from module blib/arch/auto/Tuxedo/Tuxedo.so(), but a runtime def +inition of the symbol was not found.

It goes on to complain about several other not-found-symbols before finally giving up.
It looks like something is going awry in DynaLoader.pm where "use Tuxedo;" appears in test.pl, but what?
Here is the rest of my efforts expressed as a FAQ...

Q. Does Tuxedo.so exist?
A. Yes
$ file blib/arch/auto/Tuxedo/Tuxedo.so blib/arch/auto/Tuxedo/Tuxedo.so: executable (RISC System/6000) or obje +ct module not stripped
Q. Does Tuxedo.so reference tptypes?
A. Yes
$ nm blib/arch/auto/Tuxedo/Tuxedo.so|grep tptypes .XS_Tuxedo_tptypes t 268483616 .tptypes T 268439336 .tptypes t 268439336 40 XS_Tuxedo_tptypes d 536874984 12 XS_Tuxedo_tptypes d 536876760 4 tptypes U - tptypes d 536876124 4
Q. Is your LIBPATH (AIX version of LD_LIBRARY_PATH) set correctly?
A. I think so.
$ echo $LIBPATH /opt/tuxedo/11.1_32/lib $ ls $LIBPATH/libtux.a $LIBPATH/libtux.so /opt/tuxedo/11.1_32/lib/libtux.a /opt/tuxedo/11.1_32/lib/libtux.so
Q. Is tptypes in libtux?
A. It seems to be.
$ nm /opt/tuxedo/11.1_32/lib/libtux.so|grep tptypes .tptypes T 208392 tptypes D 57036 12 $ nm /opt/tuxedo/11.1_32/lib/libtux.a|grep tptypes .tptypes T 208392 tptypes D 57036 12
Q. Have you tried debugging via DynaLoader?
A. Yes, here is debug set...
$ PERL_DL_DEBUG=1 PERL_DL_NONLAZY=1 /path/to/powerpc-AIX6.1/bin/perl " +-Iblib/lib" "-Iblib/arch" test.pl 1..1 DynaLoader.pm loaded (blib/lib blib/arch /path/to/lib/perl5/site_perl +/home/myname/lib/perl5/site_perl /path/to/perl-5.16.2/powerpc-AIX6.1/ +lib/site_perl /path/to/perl-5.16.2/powerpc-AIX6.1/lib ., /usr/local/l +ib /lib /usr/lib /usr/ccs/lib /opt/tuxedo/11.1_32/lib) DynaLoader::bootstrap for Tuxedo (auto/Tuxedo/Tuxedo.so) Can't load 'blib/arch/auto/Tuxedo/Tuxedo.so' for module Tuxedo: rtld: +0712-001 Symbol tptypes was referenced from module blib/arch/auto/Tuxedo/Tuxedo.so(), but a runtime def +inition of the symbol was not found. <snip> at test.pl line 11. Compilation failed in require at test.pl line 11. BEGIN failed--compilation aborted at test.pl line 11. not ok 1
Q. Have you tried debugging via the bootstrap file?
A. Yes, although my expertise is limited, I've tried this...
$ cat blib/arch/auto/Tuxedo/Tuxedo.bs print "Hello, dynaloader bootstrap...\n"; print "(before) dl_resolve_using=@dl_resolve_using\n"; @dl_resolve_using = dl_findfile('-ltux'); print "(after) dl_resolve_using=@dl_resolve_using\n"; $ PERL_DL_NONLAZY=1 /path/to/powerpc-AIX6.1/bin/perl "-Iblib/lib" "-Ib +lib/arch" test.pl 1..1 Hello, dynaloader bootstrap... (before) dl_resolve_using= (after) dl_resolve_using=/opt/tuxedo/11.1_32/lib/libtux.a Can't load 'blib/arch/auto/Tuxedo/Tuxedo.so' for module Tuxedo: rtld: +0712-001 Symbol tptypes was referenced from module blib/arch/auto/Tuxedo/Tuxedo.so(), but a runtime def +inition of the symbol was not found.
Q. Do you have other Perl CPAN modules that work?
A. Yes. I count several...
$ find /path/to/perl-5.16.2/ -name '*.so'|wc 68 68 4675
Q. Have you thought of moving from AIX to GNU/Linux?
A. Yes, many times! :)

Thanks for reading. If you're able to help, thanks in advance. If I can resolve this I'll post the results back here.

Regards,
-Randy

Replies are listed 'Best First'.
Re: Tuxedo CPAN module on AIX 6.1
by Corion (Patriarch) on May 22, 2015 at 06:28 UTC

    Could this be a 32bit/64bit architecture/compiler problem? Your Perl seems to be a 64bit Perl (maybe, or just using 64bit ints, I don't know AIX well):

    aix-thread-multi-64int

    ... but you're trying to use/link to 32bit libraries:

    /opt/tuxedo/11.1_32/lib/libtux.a

    If you don't resolve this otherwise, maybe showing the full output of perl -V can help us find if there is something wonky in between what the dynamic loader wants and what Perl wants and what your OS installation has.

      Hi Anonymous Monk and Corion,

      When I get into work I will post more details on the progress I've made, thanks to some insight generated by questions/suggestions made by a co-worker.

      I should have mentioned in my original post the details about 'multi-64int'. It is generally true on AIX one cannot inter-mix 32 and 64 bit object code. However, despite the 'multi-64int' being in the output, our Perl is indeed 32-bit object code. In fact, a special copy of Perl was built by our development group to avoid the 64-bit copy installed system-wide (hence the /path/to/ references).

      After reading my posting, a co-worker suggested the -G linker option may be hiding the problem, because it implies -berok (i.e. link errors are okay and should be ignored). I should add -Wl,-bernotok (i.e. link errors are *not* okay) and try again.

      This lead to the discovery that Tuxedo.so, as generated, has no references to libraries. Thus the runtime-linker has nothing to work with. We then noted an if/else block in Makefile.PL called out for different link options on Windows vs Unix and the comment in the Unix section mentioned 'tested on Solaris'. Ah, so the author may not have had the joy of working on AIX ;)

      We then adapted the link options for Windows to AIX, mostly by discarding a bunch of Windows specific libraries and repeated our efforts until we could link a Tuxedo.so when -Wl,-bernotok was on the command line.

      Thus we're past the link issue. Now on to some issues with the ubbconfig file, not passing syntax checks.

      Regards,
      -Randy

        Hi PerlMonks,

        I have managed to resolve my linking issues and have generated a patch (diff -u) for the module. This works for our environment (GCC on AIX). Alas, I could not resolve one problem. PERLSVR core dumps upon initialization. It appears to be right at the point where perl_alloc() is called. Without PERLSVR one cannot create a Perl-based Tuxedo server. Fortunately all I need is a Tuxedo client.

        I addressed a number of other issues that came up in our environment. These may not impact others, but have nonetheless been expressed in the following diff output.

        $ diff -r -u Tuxedo-2.08 tuxrepo/Tuxedo-2.08 diff -r -u Tuxedo-2.08/Changes tuxrepo/Tuxedo-2.08/Changes --- Tuxedo-2.08/Changes 2005-06-08 18:33:28 -0700 +++ tuxrepo/Tuxedo-2.08/Changes 2015-05-25 14:07:01 -0700 @@ -18,3 +18,9 @@ AIX 5.2 64bit 5.8.4 xlC 8.1 64bit RP 107 HPUX 11.11 64bit 5.8.6 cc 8.1 64bit RP 107 WinXP SP2 5.8.6 VC++ 2003 8.1 + +2.?? - add support for GCC on AIX 6.1 (sans PERLSVR unfortunately) + operating system perl compiler tuxedo version +===================================================================== += + AIX 6.1 32bit 5.16.2 gcc 4.6.3 11.1_32 + diff -r -u Tuxedo-2.08/Makefile.PL tuxrepo/Tuxedo-2.08/Makefile.PL --- Tuxedo-2.08/Makefile.PL 2005-06-08 18:33:28 -0700 +++ tuxrepo/Tuxedo-2.08/Makefile.PL 2015-05-25 14:00:01 -0700 @@ -6,6 +6,13 @@ xsinit("perlxsi.c"); my $os = $^O; +my $gcc_aix = 0; + +if ( $os eq 'aix' ) { + if (index($Config{cc}, 'gcc ') == 0) { + $gcc_aix = 1; + } +} # get the ldopts used to build perl chop(my $ldopts = ldopts); @@ -34,6 +41,46 @@ ); +if ($gcc_aix) { + $opts{clean}{FILES} .= ' aix-buildserver'; +} + + +sub Check_tmloadcf +{ + # Apparently the CPAN module FindBin can do this, but + # we which to avoid additional dependencies here. + if ( !defined($ENV{PATH}) ) + { + print "PATH not defined.\n"; + die; + } + my @dirs = split(/:/, $ENV{PATH}); + my $found = 0; + foreach my $d (@dirs) + { + if ( -x "$d/tmloadcf" ) + { + $found = 1; + print "$d/tmloadcf found.\n"; + last; + } + } + if (!$found) + { + print "tmloadcf executable not found.\n"; + die; + } +} + + +if ( !defined($ENV{TUXDIR}) ) +{ + print "TUXDIR not defined.\n"; + die; +} + + # --- How shall we link with Tuxedo? if ( $os eq 'MSWin32' ) { @@ -41,9 +88,10 @@ $opts{DEFINE} = "-D__TURBOC__"; } -# -- unix variants..tested on solaris +# -- unix variants..tested on solaris and aix else { + Check_tmloadcf(); $buildclient_cmd = `buildclient -v 2>/dev/null`; @buildclient_options = split( / /, $buildclient_cmd ); @lib_options = grep /-[LlR]/, @buildclient_options; @@ -52,11 +100,70 @@ #print "libs = $libs\n"; $opts{LIBS} = [ $libs ]; $opts{LDDLFLAGS} = $Config{lddlflags} . " " . $dynaloader_lib; + if ( $gcc_aix ) { + # -- Tested with AIX 6.1, gcc 4.6.3, Perl 5.16.2 and Tuxedo 1 +1.1. + # Your mileage may vary. + if ( !defined($ENV{LIBPATH}) ) + { + print "LIBPATH not defined.\n"; + die; + } + if ( !defined($ENV{TUXCONFIG}) ) + { + print "TUXCONFIG not defined.\n"; + print "Consider running the command:\n"; + print "export TUXCONFIG=\$(pwd)/TUXCONFIG\n"; + die; + } + $opts{LIBS} = [ "-L$ENV{TUXDIR}/lib -ltux -lbuft -lfml -lfml3 +2 -lengine" ]; + $opts{LDDLFLAGS} = $Config{lddlflags} . " -Wl,-bernotok " . $ +dynaloader_lib; + $opts{OBJECT} .= " $ENV{TUXDIR}/lib/tpinit.o"; + } } -WriteMakefile( %opts ); + +sub CreateAixScript +{ + my $string = qq{ +trap 'rm -f \$\$.\$SERVER_MAIN \$SERVER_MAIN' EXIT + +# Get CC compile command and strip out AIX-specific link options +set -A CCSERVER -- \$(CC="echo \$CC" \$TUXDIR/bin/buildserver -k \${1 +:+"\$@"} \\ + | sed -e 's/-brtl *//g' \\ + -e 's/-qstaticinline *//g' \\ + -e 's/-qrtti=all *//g') + +# Add time.h to eliminate warnings +SERVER_MAIN=\${CCSERVER[7]} + +sed '1 i\\ +#include <time.h> + +' \$SERVER_MAIN > \$\$.\$SERVER_MAIN && mv -f \$\$.\$SERVER_MAIN \$S +ERVER_MAIN + +# Execute Compilation +COMPILE_CMD=\$(echo "\${CCSERVER[@]}" | sed -e's/-Wl,-Wl,-bdynamic/-W +l,-bdynamic/') +echo COMPILE_CMD=\$COMPILE_CMD +\$COMPILE_CMD +SERVER_EXIT=\$? + +exit \$SERVER_EXIT +}; + + print "Writing aix-buildserver\n"; + open(AIXSCRIPT, ">aix-buildserver") or die; + print AIXSCRIPT "#!/usr/bin/ksh\n"; + print AIXSCRIPT $string; + close(AIXSCRIPT) or die; + chmod(0755, "aix-buildserver") or die; +} +WriteMakefile( %opts ); +if ($gcc_aix) { + CreateAixScript(); +} + sub MY::postamble { my $string = <<EOS; @@ -76,6 +183,11 @@ buildserver -o \$@ -k -s "PERL" -f "-DTMMAINEXIT \$(INST_STATIC)" EOS } +elsif ( $gcc_aix ) { + $string = $string . <<EOS; + CC="$Config{cc} $libpaths"; export CC; \$(PWD)/aix-buildserver -o + \$@ -s ":PERL" -f "\$(INST_DYNAMIC)" -f "\$(PERL_EMBED_LIBS)" +EOS +} else { $string = $string . <<EOS; CC="$Config{cc} $libpaths"; export CC; \$(TUXDIR)/bin/buildserver + -o \$@ -s ":PERL" -f "\$(INST_DYNAMIC)" -f "\$(PERL_EMBED_LIBS)" diff -r -u Tuxedo-2.08/README tuxrepo/Tuxedo-2.08/README --- Tuxedo-2.08/README 2005-06-08 18:33:28 -0700 +++ tuxrepo/Tuxedo-2.08/README 2015-05-22 09:16:11 -0700 @@ -18,7 +18,7 @@ The steps to build the module are... -1/ perl Makefile.pl +1/ perl Makefile.PL 2/ make test diff -r -u Tuxedo-2.08/genubbconfig.pl tuxrepo/Tuxedo-2.08/genubbconfi +g.pl --- Tuxedo-2.08/genubbconfig.pl 2005-06-08 18:33:28 -0700 +++ tuxrepo/Tuxedo-2.08/genubbconfig.pl 2015-05-25 14:00:38 -0700 @@ -1,5 +1,14 @@ +use Config; my $os = $^O; +my $gcc_aix = 0; +my $next_line_too = 0; + +if ( $os eq 'aix' ) { + if (index($Config{cc}, 'gcc ') == 0) { + $gcc_aix = 1; + } +} ############# Global Variables ############## my $cwd; @@ -20,6 +29,8 @@ } my $tuxconfig = $cwd . "\/TUXCONFIG"; +my $hostname_no_dots = $hostname; +$hostname_no_dots =~ s/[.]/_/g; ################################################ @@ -125,6 +136,10 @@ $hostname; /eg; + s/<HOSTNAME_NO_DOTS>/ + $hostname_no_dots; + /eg; + s/<TUXDIR>/ $ENV{TUXDIR}; /eg; @@ -141,7 +156,23 @@ get_wsnaddr() . ""; /eg; - printf UBBCONFIG $_; + # Unfortunately PERLSVR fails with AIX 6.1 and 32-bit GCC 4.6 +.3 + # for unknown reasons. The failure appears to happen in + # tpsvrinit() where perl_alloc() is called. + if (($gcc_aix) && (/^PERLSVR/)) + { + printf UBBCONFIG "#$_"; + $next_line_too = 1; + } + elsif (($gcc_aix) && ($next_line_too)) + { + printf UBBCONFIG "#$_"; + $next_line_too = 0; + } + else + { + printf UBBCONFIG $_; + } } close( TEMPLATE ); diff -r -u Tuxedo-2.08/test.pl tuxrepo/Tuxedo-2.08/test.pl --- Tuxedo-2.08/test.pl 2005-06-08 18:33:28 -0700 +++ tuxrepo/Tuxedo-2.08/test.pl 2015-05-25 13:57:39 -0700 @@ -11,8 +11,18 @@ use Tuxedo; use tpadm; use testflds; +use Config; require "genubbconfig.pl"; +my $os = $^O; +my $gcc_aix = 0; + +if ( $os eq 'aix' ) { + if (index($Config{cc}, 'gcc ') == 0) { + $gcc_aix = 1; + } +} + # Insert your test code below (better if it prints "ok 13" # (correspondingly "not ok 13") depending on the success of chunk 13 @@ -24,7 +34,14 @@ ################################################################### tuxputenv( "TUXCONFIG=" . get_tuxconfig() ); $path = tuxgetenv( "PATH" ); -tuxputenv( "PATH=$path;./blib/arch/auto/Tuxedo" ); +if ( $os eq 'MSWin32' ) +{ + tuxputenv( "PATH=$path;./blib/arch/auto/Tuxedo" ); +} +else +{ + tuxputenv( "PATH=$path:./blib/arch/auto/Tuxedo" ); +} system( "tmshutdown -y" ); gen_ubbconfig(); @@ -277,19 +294,27 @@ $string->value( "fat boy" ); printf( "\$string = " . $string->value . "\n" ); -# Test PERLSVR TOUPPER -$rval = tpcall( "TOUPPER", $string, 0, $string, $len, 0 ); -if ( $rval == -1 ) { - die ( "tpcall failed: " . tpstrerror(tperrno) . "\n" ); -} -printf( "\$string = " . $string->value . "\n" ); - -# Test PERLSVR REVERSE -$rval = tpcall( "REVERSE", $string, 0, $string, $len, 0 ); -if ( $rval == -1 ) { - die ( "tpcall failed: " . tpstrerror(tperrno) . "\n" ); +# Skip PERLSVR for AIX 6.1 32-bit GCC 4.6.3 +if ($gcc_aix) +{ + print "Skip PERLSVR for gcc on aix\n"; +} +else +{ + # Test PERLSVR TOUPPER + $rval = tpcall( "TOUPPER", $string, 0, $string, $len, 0 ); + if ( $rval == -1 ) { + die ( "tpcall failed: " . tpstrerror(tperrno) . "\n" ); + } + printf( "\$string = " . $string->value . "\n" ); + + # Test PERLSVR REVERSE + $rval = tpcall( "REVERSE", $string, 0, $string, $len, 0 ); + if ( $rval == -1 ) { + die ( "tpcall failed: " . tpstrerror(tperrno) . "\n" ); + } + printf( "\$string = " . $string->value . "\n" ); } -printf( "\$string = " . $string->value . "\n" ); # TEST 5: tpterm $rval = tpterm(); diff -r -u Tuxedo-2.08/ubbconfig.template tuxrepo/Tuxedo-2.08/ubbconfi +g.template --- Tuxedo-2.08/ubbconfig.template 2005-06-08 18:33:28 -0700 +++ tuxrepo/Tuxedo-2.08/ubbconfig.template 2015-05-22 12:05:17 -070 +0 @@ -1,19 +1,21 @@ *RESOURCES IPCKEY <IPCKEY> MODEL SHM -MASTER <HOSTNAME> +MASTER <HOSTNAME_NO_DOTS> +MAXACCESSERS 100 +MAXSERVERS 120 *MACHINES "<HOSTNAME>" - LMID="<HOSTNAME>" + LMID="<HOSTNAME_NO_DOTS>" TUXDIR="<TUXDIR>" APPDIR="<APPDIR>" TUXCONFIG="<TUXCONFIG>" MAXWSCLIENTS=10 *GROUPS -TUXGRP LMID=<HOSTNAME> GRPNO=1 -APPGRP LMID=<HOSTNAME> GRPNO=2 +TUXGRP LMID=<HOSTNAME_NO_DOTS> GRPNO=1 +APPGRP LMID=<HOSTNAME_NO_DOTS> GRPNO=2 *SERVERS #WSL SRVID=1 SRVGRP=TUXGRP

        Regards,
        -Randy

Re: Tuxedo CPAN module on AIX 6.1
by Anonymous Monk on May 22, 2015 at 00:46 UTC