The INIT_ARGV_and_ENVIRON macro defined in sysdeps/generic/bp-start.h (and called from __libc_start_main()) sets the global __environ pointer. Unfortunately, this overrides any changes to __environ that were made by __add_to_environ() in sysdeps/generic/setenv.c. This causes problems for dynamically linked libraries whose _init() function calls setenv(), since the dynamic library initialization occurs before __libc_start_main() runs. (Actually, it looks like __environ may be uninitialized if setenv() is called from a dynamic library intializer, but I'm not certain.) This is with glibc source code version 2.3.3 (unmodified, straigt from the tar file). Here's an example program which illustrates this behavior: -- envlib.cc: #include <stdlib.h> struct PreEnvlibSetter { PreEnvlibSetter() { setenv("ENVLIB_PRE", "1", 1); } }; static PreEnvlibSetter dummy1; // gets called before main() is called struct PostEnvlibSetter { PostEnvlibSetter() { setenv("ENVLIB_POST", "1", 1); } }; void EnvlibSetter() { PostEnvlibSetter dummy2; // gets called after main() is called } -- env.cc: #include <stdio.h> #include <stdlib.h> struct PreEnvSetter { PreEnvSetter() { setenv("ENV_PRE", "1", 1); } }; static PreEnvSetter dummy3; // gets called before main() is called struct PostEnvSetter { PostEnvSetter() { setenv("ENV_POST", "1", 1); } }; void EnvSetter() { // gets called after main() is called PostEnvSetter dummy4; } void EnvlibSetter(); int main(int argc, char** argv) { EnvlibSetter(); EnvSetter(); printf("envlib-pre: %s\nenvlib-post: %s\nenv-pre: %s\nenv-post: %s\n", getenv("ENVLIB_PRE"), getenv("ENVLIB_POST"), getenv("ENV_PRE"), getenv("ENV_POST")); return 0; } -- When I compile in one unit, everything works as I'd expect: % gcc env.cc envlib.cc -lstdc++ % ./a.out envlib-pre: 1 envlib-post: 1 env-pre: 1 env-post: 1 But when I put envlib into a shared library, ENVLIB_PRE doesn't "stick": % gcc -shared envlib.cc -oenvlib.so % gcc env.cc `pwd`/envlib.so -lstdc++ % ./a.out envlib-pre: (null) envlib-post: 1 env-pre: 1 env-post: 1 Also: % gcc --version gcc (GCC) 3.2.2 20030222 (Red Hat Linux 3.2.2-5) Copyright (C) 2002 Free Software Foundation, Inc. craig
*** This bug has been marked as a duplicate of 727 ***