lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <485b8b48-673a-4b1d-8651-2c0038d478cf@t-8ch.de>
Date:   Sat, 7 Oct 2023 09:28:45 +0200
From:   Thomas Weißschuh <linux@...ssschuh.net>
To:     Willy Tarreau <w@....eu>
Cc:     Shuah Khan <shuah@...nel.org>, linux-kernel@...r.kernel.org,
        linux-kselftest@...r.kernel.org
Subject: Re: [PATCH RFC] tools/nolibc: add support for constructors and
 destructors

Hi Willy,

On 2023-10-07 08:50:25+0200, Willy Tarreau wrote:
> On Thu, Oct 05, 2023 at 06:45:07PM +0200, Thomas Weißschuh wrote:
> > With the startup code moved to C, implementing support for
> > constructors and deconstructors is fairly easy to implement.

> [..]

> > diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> > index a3ee4496bf0a..f166b425613a 100644
> > --- a/tools/testing/selftests/nolibc/nolibc-test.c
> > +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> > @@ -57,6 +57,9 @@ static int test_argc;
> >  /* will be used by some test cases as readable file, please don't write it */
> >  static const char *argv0;
> >  
> > +/* will be used by constructor tests */
> > +static int constructor_test_value;
> > +
> >  /* definition of a series of tests */
> >  struct test {
> >  	const char *name;              /* test name */
> > @@ -594,6 +597,18 @@ int expect_strne(const char *expr, int llen, const char *cmp)
> >  #define CASE_TEST(name) \
> >  	case __LINE__: llen += printf("%d %s", test, #name);
> >  
> > +__attribute__((constructor))
> > +static void constructor1(void)
> > +{
> > +	constructor_test_value = 1;
> > +}
> > +
> > +__attribute__((constructor))
> > +static void constructor2(void)
> > +{
> > +	constructor_test_value *= 2;
> > +}
> > +
> 
> In the past I learned the hard way that you can never trust the execution
> order of constructors, so if you're unlucky above you could very well end
> up with 1 and that would be correct. I suggest that instead you do something
> such as:
> 
>       constructor_test_value += 1;
> ...
>       constructor_test_value += 2;
> 
> and check for value 3 in the test to make sure they were both executed
> exactly once each.

Was this indeterminism for constructors from the same translation unit?
Or across different translation units/shared objects?


I'm not entirely sure, but the GCC [0] docs could be read that within a
given TU the execution order for constructors is the same as the
definition order, even for C.

    The priorities for constructor and destructor functions are the same
    as those specified for namespace-scope C++ objects

And linked from there:

    In Standard C++, objects defined at namespace scope are guaranteed
    to be initialized in an order in strict accordance with that of
    their definitions *in a given translation unit*. No guarantee is made
    for initializations across translation units.


[0] https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html
(using an old version of the docs to make sure this didn't change recently)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ