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: 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 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 40 int Get() const { return x_; } 41 42 private: 43 int x_; 44 }; 45 46 A s_a; 47 48 extern "C" int Foo() { return s_a.Get(); } 49