This is the mail archive of the
glibc-bugs@sources.redhat.com
mailing list for the glibc project.
[Bug libc/863] New: __libc_start_main() resets __environ
- From: "csilvers at google dot com" <sourceware-bugzilla at sources dot redhat dot com>
- To: glibc-bugs at sources dot redhat dot com
- Date: 20 Apr 2005 19:52:23 -0000
- Subject: [Bug libc/863] New: __libc_start_main() resets __environ
- Reply-to: sourceware-bugzilla at sources dot redhat dot com
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
--
Summary: __libc_start_main() resets __environ
Product: glibc
Version: 2.3.3
Status: NEW
Severity: normal
Priority: P2
Component: libc
AssignedTo: gotom at debian dot or dot jp
ReportedBy: csilvers at google dot com
CC: glibc-bugs at sources dot redhat dot com
GCC build triplet: any
GCC host triplet: any
GCC target triplet: any
http://sources.redhat.com/bugzilla/show_bug.cgi?id=863
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.