From 611cdccd9690a9083816f6d4746e998d58250a86 Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Thu, 28 May 2009 17:37:31 +0200 Subject: [PATCH] Add a new unit test that checks that the static C++ constructors of shared libraries and dynamic executables are called only once, and in the correct order. --- tests/bionic/libc/Android.mk | 19 +++++++++++++++++ tests/bionic/libc/bionic/lib_static_init.cpp | 18 ++++++++++++++++ tests/bionic/libc/bionic/lib_static_init.h | 15 ++++++++++++++ tests/bionic/libc/bionic/test_static_init.cpp | 30 +++++++++++++++++++++++++++ 4 files changed, 82 insertions(+) create mode 100644 tests/bionic/libc/bionic/lib_static_init.cpp create mode 100644 tests/bionic/libc/bionic/lib_static_init.h create mode 100644 tests/bionic/libc/bionic/test_static_init.cpp diff --git a/tests/bionic/libc/Android.mk b/tests/bionic/libc/Android.mk index c7e7305d..4e4bcc64 100644 --- a/tests/bionic/libc/Android.mk +++ b/tests/bionic/libc/Android.mk @@ -30,6 +30,7 @@ define device-test $(eval include $(CLEAR_VARS)) \ $(eval LOCAL_SRC_FILES := $(file)) \ $(eval LOCAL_MODULE := $(notdir $(file:%.c=%))) \ + $(eval LOCAL_MODULE := $(LOCAL_MODULE:%.cpp=%)) \ $(eval $(info LOCAL_MODULE=$(LOCAL_MODULE))) \ $(eval LOCAL_CFLAGS += $(EXTRA_CFLAGS)) \ $(eval LOCAL_MODULE_TAGS := tests) \ @@ -46,6 +47,7 @@ define host-test $(eval include $(CLEAR_VARS)) \ $(eval LOCAL_SRC_FILES := $(file)) \ $(eval LOCAL_MODULE := $(notdir $(file:%.c=%))) \ + $(eval LOCAL_MODULE := $(LOCAL_MODULE:%.cpp=%)) \ $(eval $(info LOCAL_MODULE=$(LOCAL_MODULE) file=$(file))) \ $(eval LOCAL_CFLAGS += $(EXTRA_CFLAGS)) \ $(eval LOCAL_LDLIBS += $(EXTRA_LDLIBS)) \ @@ -128,6 +130,23 @@ LOCAL_MODULE := test_relocs LOCAL_SHARED_LIBRARIES := libtest_relocs include $(BUILD_EXECUTABLE) +# This test tries to see if the static constructors in a +# shared library are only called once. We thus need to +# build a shared library, then call it from another +# program. +# +include $(CLEAR_VARS) +LOCAL_SRC_FILES := bionic/lib_static_init.cpp +LOCAL_MODULE := libtest_static_init +LOCAL_PRELINK_MODULE := false +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES := bionic/test_static_init.cpp +LOCAL_MODULE := test_static_init +LOCAL_SHARED_LIBRARIES := libtest_static_init +include $(BUILD_EXECUTABLE) + # TODO: Add a variety of GLibc test programs too... # Hello World to test libstdc++ support diff --git a/tests/bionic/libc/bionic/lib_static_init.cpp b/tests/bionic/libc/bionic/lib_static_init.cpp new file mode 100644 index 00000000..d847110a --- /dev/null +++ b/tests/bionic/libc/bionic/lib_static_init.cpp @@ -0,0 +1,18 @@ +#include "lib_static_init.h" +#include + +Foo::Foo() +{ + /* increment the static variable */ + value = ++Foo::counter; + fprintf(stderr, "Foo::Foo for this=%p called (counter = %d)\n", this, counter); +} + +int Foo::getValue() +{ + return value; +} + +int Foo::counter; + +Foo theFoo; diff --git a/tests/bionic/libc/bionic/lib_static_init.h b/tests/bionic/libc/bionic/lib_static_init.h new file mode 100644 index 00000000..f455de8e --- /dev/null +++ b/tests/bionic/libc/bionic/lib_static_init.h @@ -0,0 +1,15 @@ +#ifndef _lib_static_init_h +#define _lib_static_init_h + +class Foo { +private: + int value; + static int counter; +public: + virtual int getValue(); + Foo(); +}; + +extern Foo theFoo; + +#endif /* _lib_static_init_h */ diff --git a/tests/bionic/libc/bionic/test_static_init.cpp b/tests/bionic/libc/bionic/test_static_init.cpp new file mode 100644 index 00000000..cbc4a59d --- /dev/null +++ b/tests/bionic/libc/bionic/test_static_init.cpp @@ -0,0 +1,30 @@ +#include +#include +#include "lib_static_init.h" + +Foo theFoo2; + +int main(int argc, char** argv) +{ + int c = theFoo.getValue(); + + /* check the counter on the library object + * it must have been called first, and only once + */ + if (c != 1) { + printf("KO (counter(shared) == %d, expected 1)\n", c); + return 1; + } + + /* check the counter on the executable object, + * it must have been called second, and only once + */ + c = theFoo2.getValue(); + if (c != 2) { + printf("KO (counter(executable) == %d, expected 2)\n", c); + return 1; + } + + printf("OK\n"); + return 0; +} -- 2.11.0