[Development] Modifying and accessing environment variables in Qt

Simon Hausmann simon.hausmann at theqtcompany.com
Thu Apr 30 10:06:05 CEST 2015


On Thursday, April 30, 2015 10:50:59 AM Marc Mutz wrote:
> > > 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.

That is a valid point, for sure. Inherently valid due to the nature of the way 
the C runtime implements this and is accessible to everyone.

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

I think you may be misunderstanding me. I don't want to fix all races, I want 
to fix the common cases in Qt, in particular the ones that affect our everyday 
work of trying to integrate changes by passing tests. I'm looking for a 
pragmatic improvement, not a perfect solution. I see however that you agree to 
the proposed change being acceptable as a stop-gap - so thank you :)
 
> > > 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.

Can you elaborate on that? I don't think I fully understand what you mean.

The only portable solution that I can think of is to replace each use of an 
environment variable with an autotest-only exported variable in Qt, that is 
used instead. That may be a path forward and I'd be happy to help review 
changes towards that.

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

No, I do not claim that threads are created before the Q*Application 
constructor runs. Please re-read what I wrote. I said that the platform 
plugins start threads, and they are loaded in the Q*Application constructor. 
So environment variables have to be set before there, if they affect the 
platform plugins.


Simon



More information about the Development mailing list