1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // This source file must contain a static destructor to check that
6 // the crazy linker can resolve weak symbols from the C library,
7 // like __aeabi_atexit(), which are not normally returned by
8 // a call to dlsym().
9 
10 // Libc is not required to copy strings passed to putenv(). If it does
11 // not then env pointers become invalid when rodata is unmapped on
12 // library unload. To guard against this, putenv() strings are first
13 // strdup()'ed. This is a mild memory leak.
14 
15 #include <stdlib.h>
16 
17 #ifdef __arm__
18 extern "C" void __aeabi_atexit(void*);
19 #endif
20 
21 class A {
22  public:
A()23   A() {
24     x_ = rand();
25     const char* env = getenv("TEST_VAR");
26     if (!env || strcmp(env, "INIT"))
27       putenv(strdup("TEST_VAR=LOAD_ERROR"));
28     else
29       putenv(strdup("TEST_VAR=LOADED"));
30   }
31 
~A()32   ~A() {
33     const char* env = getenv("TEST_VAR");
34     if (!env || strcmp(env, "LOADED"))
35       putenv(strdup("TEST_VAR=UNLOAD_ERROR"));
36     else
37       putenv(strdup("TEST_VAR=UNLOADED"));
38   }
39 
Get() const40   int Get() const { return x_; }
41 
42  private:
43   int x_;
44 };
45 
46 A s_a;
47 
Foo()48 extern "C" int Foo() { return s_a.Get(); }
49