[Development] Modifying and accessing environment variables in Qt

Marc Mutz marc.mutz at kdab.com
Thu Apr 30 10:50:59 CEST 2015


On Wednesday 29 April 2015 11:15:21 Simon Hausmann wrote:
> > 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)

See my other mail. It prevents putenv/putenv races, but not putenv/getenv, indeed.

> > 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.

This is my main point.

> > 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? 

You want to fix races between environment accesses. I'm saying that libc functions 
are implicitly accessing the environment, too, and you cannot insert you Qt mutex 
there. So this is isn't really orthogonal.
 
> > 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?

Tests are presumably easy. If everything else fails, QtTest could execute itself 
anew for each test. After a quick scan, the only thing I'm worried about in QtBase 
is qglxconvenience.cpp, which temporarily modifies the environment.

> 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().

Platform plugins are creating threads before the Q*Application ctor runs? How is 
that possible if the Q*Application ctor is the first Qt code that gets called from 
the application? If they do, it means that the threads are already running when 
control enters main(). And that's unacceptable, because it deprives application 
authors of the window of control where there's only one thread of execution. 
Guaranteed. So you cannot, say, use gpgme with a Qt program.

Qt can't make the rules. It has to abide by them.

As an aside: That so much code in Qt checks the environment for some more-or-less 
obscure options indicates the need for explicit management of these options. I'll 
give this some more thought.

Thanks,
Marc

-- 
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt Experts



More information about the Development mailing list