[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