[Development] Modifying and accessing environment variables in Qt

Simon Hausmann simon.hausmann at theqtcompany.com
Wed Apr 29 11:15:21 CEST 2015


On Wednesday, April 29, 2015 11:55:48 AM Marc Mutz wrote:
> On Tuesday 28 April 2015 10:52:32 Simon Hausmann wrote:
> > There are various options about what we can do with different degrees of
> > "perfection", but ultimately it's all going to require a compromise. The
> > option that we are favoring at the moment is two-fold:
> > 
> > 1) Policy in Qt is to use the Qt wrappers for accessing the environment
> > (qgetenv, etc.).
> > 
> > 2) These functions we protect with a mutex.
> > 
> > Yes, this isn't perfect, because we still include large quantities of code
> > in src/3rdparty in Qt that has unprotected calls to getenv(). But then
> > that hasn't stopped us from patching that code in the past.
> 
> From Gerrit, expanded here and there:
> 
> I don't believe this is the right fix.
> 
> 1. man putenv on Linux says that since glibc 2.1, putenv is reentrant. In
>    any case, it's almost trivial to fix this in libc (using CAS, as Ossi
>    suggested in a comment on v1 of the patch), but impossible outside.

Does reentrancy here refer to the supplied arguments of putenv? Can you 
explain how this helps with concurrent getenv invocations?

(Sorry, I must be missing something - I don't see how this relates to the 
crashes)

> 2. what business does a program have, anyway, of modifying the environment
>    after threads may have started? Such code should be fixed. Making the Qt
>    wrappers "save" could lead to more code doing nonsense instead of being
>    fixed.
>
> 3. C functions such as localtime(3) are calling tzset(3) which reads TZ.
>    You may be able to patch 3rd-party code, but you cannot patch libc.

Right, there are more "unsafe" functions in libc that we cannot change. But 
isn't that an orthogonal topic to the issue of our tests crashing?
 
> Callers of putenv()/setenv() should be fixed to not do so after initial
> initialisation, ie. when threads may have started. This is how most
> initialisation in libraries is required to be handled, see e.g.
>  https://www.gnupg.org/documentation/manuals/gpgme/Library-Version-Check.htm
> l and I don't see why Qt should do something different from every other
> C/C++ library on the planet, at least not for such a common problem as
> library initialisation.

How can we do this in Qt and in our tests?

It would all have to be done before the application constructor, because 
already our platform plugins start threads. This is in contrast to individual 
test functions in Qt calling putenv().


Simon



More information about the Development mailing list