C++ cgi problem.


R. Clayton (rclayton@monmouth.edu)
(no date)


Last night a colleague of yours pointed out to me a problem with using c++
programs as cgi programs. This problem exists for any program that depends on
the execution environment to supply information via environment variables. C++
(and c) programs have this problem, as do java programs and probably others
too.

Under normal linking, c++ executables contain undefined procedures. When the
program tries to execute one of these undefined procedures, the operating
system will load the procedure into the executable from the library specified
during linking; this is known as dynamic linking. The operating system looks
in several standard directories for libraries (including /usr/lib), but it
also uses the directory list given in the environment variable LD_LIBRARY_PATH
to look for non-standard libraries.

When you link your program with g++, you use several non-standard (to solaris)
libraries, and you must specify their directory locations via LD_LIBRARY_PATH
or solaris won't find them.

  $ cat t.cc
  #include <iostream>

  int main() {
    std::cout << "Hello world!\n";
    }

  $ g++ -o t t.cc

  $ echo $LD_LIBRARY_PATH
  /export/opt/gcc3/lib

  $ ./t
  Hello world!

  $ LD_LIBRARY_PATH='' ./t
  ld.so.1: ./t: fatal: libstdc++.so.3: open failed: No such file or directory
  Killed

Normally, you wouldn't have to worry about this because LD_LIBRARY_PATH is set
correctly when you log in. However, your colleague's problem arose because the
http server does not include LD_LIBRARY_PATH in the cgi program's execution
environment, and so solaris can't resolve the non-standard gnu procedures
executed by the c++ program.

There are a couple of ways to solve this problem. The first is to use the
solaris standard c++ compiler CC on your programs. Because CC is part of
solaris, the default library directories are all that's needed and
LD_LIBRARY_PATH isn't necessary.

  $ CC -o t t.cc

  $ ./t
  Hello world!

  $ LD_LIBRARY_PATH='' ./t
  Hello world!

  $

The other approach is to force g++ to load all unresolved procedures at link
time so the program executes with no unresolved procedures and there's nothing
to dynamically link at runtime. The -static option forces link-time
resolution.

  $ g++ -o t -static t.cc

  $ ./t
  Hello world!

  $ LD_LIBRARY_PATH='' ./t
  Hello world!

  $

Note that statically linked executables tend to be much larger than dynamically
linked ones.

  $ g++ -o t -static t.cc

  $ size ./t
     text data bss dec hex filename
  406,400 48,413 21,864 47,6677 74605 ./t

  $ g++ -o t t.cc

  $ size ./t
     text data bss dec hex filename
   24,144 3,098 196 27,438 6b2e ./t

  $



This archive was generated by hypermail 2.0b3 on Wed May 15 2002 - 12:00:04 EDT