diff --git a/libports/lib/mk/test-ldso.mk b/libports/lib/mk/test-ldso.mk
deleted file mode 100644
index 9ede73aa3..000000000
--- a/libports/lib/mk/test-ldso.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-SRC_CC = test-rtld.cc
-SHARED_LIB = yes
-INC_DIR += $(REP_DIR)/src/test/ldso/include
-
-LIBS = test-ldso2
-
-vpath test-rtld.cc $(REP_DIR)/src/test/ldso/lib
diff --git a/libports/lib/mk/test-ldso2.mk b/libports/lib/mk/test-ldso2.mk
deleted file mode 100644
index f52b69100..000000000
--- a/libports/lib/mk/test-ldso2.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-SRC_CC = test_lib.cc
-SHARED_LIB = yes
-INC_DIR += $(REP_DIR)/src/test/ldso/include
-
-vpath test_lib.cc $(REP_DIR)/src/test/ldso/lib
diff --git a/libports/lib/mk/test-ldso_lib_1.mk b/libports/lib/mk/test-ldso_lib_1.mk
new file mode 100644
index 000000000..10c085c5e
--- /dev/null
+++ b/libports/lib/mk/test-ldso_lib_1.mk
@@ -0,0 +1,5 @@
+SRC_CC = lib_1.cc
+SHARED_LIB = yes
+INC_DIR += $(REP_DIR)/src/test/ldso/include
+LIBS = test-ldso_lib_2
+vpath % $(REP_DIR)/src/test/ldso
diff --git a/libports/lib/mk/test-ldso_lib_2.mk b/libports/lib/mk/test-ldso_lib_2.mk
new file mode 100644
index 000000000..bd9497122
--- /dev/null
+++ b/libports/lib/mk/test-ldso_lib_2.mk
@@ -0,0 +1,4 @@
+SRC_CC = lib_2.cc
+SHARED_LIB = yes
+INC_DIR += $(REP_DIR)/src/test/ldso/include
+vpath % $(REP_DIR)/src/test/ldso
diff --git a/libports/src/test/ldso/include/test-ldso.h b/libports/src/test/ldso/include/test-ldso.h
index 88a396339..d3ae81d38 100644
--- a/libports/src/test/ldso/include/test-ldso.h
+++ b/libports/src/test/ldso/include/test-ldso.h
@@ -1,6 +1,7 @@
/*
* \brief ldso test program
* \author Sebastian Sumpf
+ * \author Martin Stein
* \date 2009-11-05
*/
@@ -11,14 +12,44 @@
* under the terms of the GNU General Public License version 2.
*/
-#ifndef _INCLUDE_RTLD_RTLD_LIB_H
-#define _INCLUDE_RTLD_RTLD_LIB_H
+#ifndef _TEST_LDSO_H_
+#define _TEST_LDSO_H_
-namespace Link {
- void dynamic_link_test();
- void static_function_object();
- void cross_lib_exception();
- void raise_exception();
+void lib_1_test();
+void lib_1_exception();
+void lib_2_exception();
+
+struct Lib_1_local_3
+{
+ int x { 0x12345678 };
+ Lib_1_local_3();
+ void lib_1_local_3();
+ ~Lib_1_local_3();
+};
+
+Lib_1_local_3 * lib_1_local_3();
+
+struct Lib_2_global
+{
+ int x { 0x11223344 };
+ Lib_2_global();
+ void lib_2_global();
+ ~Lib_2_global();
}
-#endif
+extern lib_2_global;
+
+struct Lib_2_local
+{
+ int x { 0x55667788 };
+ Lib_2_local();
+ void lib_2_local();
+ ~Lib_2_local();
+};
+
+Lib_2_local * lib_2_local();
+
+extern unsigned lib_1_pod_1;
+extern unsigned lib_2_pod_1;
+
+#endif /* _TEST_LDSO_H_ */
diff --git a/libports/src/test/ldso/lib/test-rtld.cc b/libports/src/test/ldso/lib/test-rtld.cc
deleted file mode 100644
index 74d9300e5..000000000
--- a/libports/src/test/ldso/lib/test-rtld.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * \brief ldso test library
- * \author Sebastian Sumpf
- * \date 2009-10-26
- */
-
-/*
- * Copyright (C) 2009-2013 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU General Public License version 2.
- */
-
-/* Genode includes */
-#include
-#include
-/* shared-lib includes */
-#include "test-ldso.h"
-
-using namespace Genode;
-
-class Static_test
-{
- public:
- void print_signature()
- {
- printf("a: %08lx b: %08lx c: %08lx 6: %08lx\n", _a, _b, _c, _6);
- }
-
- Static_test() : _a(0xaaaaaaaa), _b(0xbbbbbbbb),
- _c(0xcccccccc), _6(0x666)
- {}
-
- private:
- unsigned long _a, _b, _c, _6;
-
-};
-
-static Static_test _static;
-
-static void __raise_exception()
-{
- throw 666;
-}
-
-void Link::raise_exception()
-{
- throw Genode::Rm_session::Region_conflict();
-}
-
-void Link::static_function_object()
-{
- static Static_test local_static;
- local_static.print_signature();
-}
-
-void Link::dynamic_link_test()
-{
- printf("good\n");
-
- printf("Ctor in shared lib ... ");
- _static.print_signature();
-
- printf("Exception in shared lib ... ");
-
- try {
- __raise_exception();
- }
- catch (...) {
- printf("good (library)\n");
- }
-
- printf("Cross library exception ... ");
-
- try {
- Link::cross_lib_exception();
- }
- catch(...) {
- printf("good (cross library)\n");
- }
-}
diff --git a/libports/src/test/ldso/lib/test_lib.cc b/libports/src/test/ldso/lib/test_lib.cc
deleted file mode 100644
index 6b0b41ffd..000000000
--- a/libports/src/test/ldso/lib/test_lib.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * \brief Test for cross library linking
- * \author Sebastian Sumpf
- * \date 2011-07-20
- */
-
-/*
- * Copyright (C) 2011-2013 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU General Public License version 2.
- */
-#include
-#include "test-ldso.h"
-
-void Link::cross_lib_exception() { throw 668; }
diff --git a/libports/src/test/ldso/lib_1.cc b/libports/src/test/ldso/lib_1.cc
new file mode 100644
index 000000000..c3a5f2530
--- /dev/null
+++ b/libports/src/test/ldso/lib_1.cc
@@ -0,0 +1,149 @@
+/*
+ * \brief ldso test library
+ * \author Sebastian Sumpf
+ * \author Martin Stein
+ * \date 2009-10-26
+ */
+
+/*
+ * Copyright (C) 2009-2013 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+/* Genode includes */
+#include
+#include
+
+/* local includes */
+#include
+
+using namespace Genode;
+
+
+/********************************************************************
+ ** Helpers to test construction and destruction of global objects **
+ ********************************************************************/
+
+struct Lib_1_global_1
+{
+ int x { 0x05060708 };
+ Lib_1_global_1() { printf("%s %x\n", __func__, --x); }
+ void lib_1_global_1() { printf("%s %x\n", __func__, --x); }
+ ~Lib_1_global_1() { printf("%s %x\n", __func__, --x); x=0; }
+}
+lib_1_global_1;
+
+static struct Lib_1_global_2
+{
+ int x { 0x01020304 };
+ Lib_1_global_2() { printf("%s %x\n", __func__, --x); }
+ void lib_1_global_2() { printf("%s %x\n", __func__, --x); }
+ ~Lib_1_global_2() { printf("%s %x\n", __func__, --x); x=0; }
+}
+lib_1_global_2;
+
+
+/**************************************************************************
+ ** Helpers to test construction and destruction of local static objects **
+ **************************************************************************/
+
+struct Lib_1_local_1
+{
+ int x { 0x50607080 };
+ Lib_1_local_1() { printf("%s %x\n", __func__, --x); }
+ void lib_1_local_1() { printf("%s %x\n", __func__, --x); }
+ ~Lib_1_local_1() { printf("%s %x\n", __func__, --x); x=0; }
+};
+
+struct Lib_1_local_2
+{
+ int x { 0x10203040 };
+ Lib_1_local_2() { printf("%s %x\n", __func__, --x); }
+ void lib_1_local_2() { printf("%s %x\n", __func__, --x); }
+ ~Lib_1_local_2() { printf("%s %x\n", __func__, --x); x=0; }
+};
+
+Lib_1_local_3::Lib_1_local_3() { printf("%s %x\n", __func__, --x); }
+void Lib_1_local_3::lib_1_local_3() { printf("%s %x\n", __func__, --x); }
+Lib_1_local_3::~Lib_1_local_3() { printf("%s %x\n", __func__, --x); x=0; }
+
+Lib_1_local_1 * lib_1_local_1()
+{
+ static Lib_1_local_1 s;
+ return &s;
+}
+
+static Lib_1_local_2 * lib_1_local_2()
+{
+ static Lib_1_local_2 s;
+ return &s;
+}
+
+Lib_1_local_3 * lib_1_local_3()
+{
+ static Lib_1_local_3 s;
+ return &s;
+}
+
+
+/************************************************************************
+ ** Helpers to test function attributes 'constructor' and 'destructor' **
+ ** **
+ ** FIXME: We don't assume attribute 'destructor' to work in shared **
+ ** libraries by now as dtors of such libraries are not called **
+ ** by the dynamic linker. **
+ ************************************************************************/
+
+ unsigned lib_1_pod_1 { 0x80706050 };
+static unsigned lib_1_pod_2 { 0x40302010 };
+
+static void lib_1_attr_constructor_1()__attribute__((constructor));
+ void lib_1_attr_constructor_2()__attribute__((constructor));
+
+ void lib_1_attr_destructor_1() __attribute__((destructor));
+static void lib_1_attr_destructor_2() __attribute__((destructor));
+
+static void lib_1_attr_constructor_1() { printf("%s %x\n", __func__, --lib_1_pod_1); }
+ void lib_1_attr_constructor_2() { printf("%s %x\n", __func__, --lib_1_pod_2); }
+
+ void lib_1_attr_destructor_1() { printf("%s %x\n", __func__, --lib_1_pod_1); lib_1_pod_1=0; }
+static void lib_1_attr_destructor_2() { printf("%s %x\n", __func__, --lib_1_pod_2); lib_1_pod_2=0; }
+
+
+
+static void exception() { throw 666; }
+
+void lib_1_exception() { throw Genode::Rm_session::Region_conflict(); }
+
+void lib_1_test()
+{
+ printf("global objects and local static objects of shared lib\n");
+ printf("-----------------------------------------------------\n");
+ lib_1_global_1.lib_1_global_1();
+ lib_1_global_2.lib_1_global_2();
+ lib_1_local_1()->lib_1_local_1();
+ lib_1_local_2()->lib_1_local_2();
+ printf("lib_1_pod_1 %x\n", --lib_1_pod_1);
+ printf("lib_1_pod_2 %x\n", --lib_1_pod_2);
+ printf("\n");
+
+ printf("Access shared lib from another shared lib\n");
+ printf("-----------------------------------------\n");
+ lib_2_global.lib_2_global();
+ lib_2_local()->lib_2_local();
+ printf("lib_2_pod_1 %x\n", --lib_2_pod_1);
+ printf("\n");
+
+ printf("Catch exceptions in shared lib\n");
+ printf("------------------------------\n");
+ printf("exception in lib: ");
+ try { exception(); }
+ catch (...) { printf("caught\n"); }
+
+ printf("exception in another shared lib: ");
+ try { lib_2_exception(); }
+ catch(...) { printf("caught\n"); }
+ printf("\n");
+}
diff --git a/libports/src/test/ldso/lib_2.cc b/libports/src/test/ldso/lib_2.cc
new file mode 100644
index 000000000..1ac9fb35a
--- /dev/null
+++ b/libports/src/test/ldso/lib_2.cc
@@ -0,0 +1,37 @@
+/*
+ * \brief Test for cross library linking
+ * \author Sebastian Sumpf
+ * \author Martin Stein
+ * \date 2011-07-20
+ */
+
+/*
+ * Copyright (C) 2011-2013 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+#include
+#include "test-ldso.h"
+
+using namespace Genode;
+
+void lib_2_exception() { throw 668; }
+
+Lib_2_global::Lib_2_global() { printf("%s %x\n", __func__, --x); }
+void Lib_2_global::lib_2_global() { printf("%s %x\n", __func__, --x); }
+Lib_2_global::~Lib_2_global() { printf("%s %x\n", __func__, --x); x=0; }
+
+Lib_2_global lib_2_global;
+
+Lib_2_local::Lib_2_local() { printf("%s %x\n", __func__, --x); }
+void Lib_2_local::lib_2_local() { printf("%s %x\n", __func__, --x); }
+Lib_2_local::~Lib_2_local() { printf("%s %x\n", __func__, --x); x=0; }
+
+Lib_2_local * lib_2_local()
+{
+ static Lib_2_local s;
+ return &s;
+}
+
+unsigned lib_2_pod_1 { 0x87654321 };
diff --git a/libports/src/test/ldso/main.cc b/libports/src/test/ldso/main.cc
index 38256e438..105f365fe 100644
--- a/libports/src/test/ldso/main.cc
+++ b/libports/src/test/ldso/main.cc
@@ -25,63 +25,148 @@ namespace Libc {
#include
}
-static void __raise_exception(void)
+
+/********************************************************************
+ ** Helpers to test construction and destruction of global objects **
+ ********************************************************************/
+
+struct Global_1
{
- throw 666;
+ int x { 0x05060708 };
+ Global_1() { printf("%s %x\n", __func__, --x); }
+ void global_1() { printf("%s %x\n", __func__, --x); }
+ ~Global_1() { printf("%s %x\n", __func__, --x); x=0; }
}
+global_1;
+
+static struct Global_2
+{
+ int x { 0x01020304 };
+ Global_2() { printf("%s %x\n", __func__, --x); }
+ void global_2() { printf("%s %x\n", __func__, --x); }
+ ~Global_2() { printf("%s %x\n", __func__, --x); x=0; }
+}
+global_2;
+
+
+/**************************************************************************
+ ** Helpers to test construction and destruction of local static objects **
+ **************************************************************************/
+
+struct Local_1
+{
+ int x { 0x50607080 };
+ Local_1() { printf("%s %x\n", __func__, --x); }
+ void local_1() { printf("%s %x\n", __func__, --x); }
+ ~Local_1() { printf("%s %x\n", __func__, --x); x=0; }
+};
+
+struct Local_2
+{
+ int x { 0x10203040 };
+ Local_2() { printf("%s %x\n", __func__, --x); }
+ void local_2() { printf("%s %x\n", __func__, --x); }
+ ~Local_2() { printf("%s %x\n", __func__, --x); x=0; }
+};
+
+Local_1 * local_1()
+{
+ static Local_1 s;
+ return &s;
+}
+
+static Local_2 * local_2()
+{
+ static Local_2 s;
+ return &s;
+}
+
+
+/************************************************************************
+ ** Helpers to test function attributes 'constructor' and 'destructor' **
+ ************************************************************************/
+
+ unsigned pod_1 { 0x80706050 };
+static unsigned pod_2 { 0x40302010 };
+
+static void attr_constructor_1()__attribute__((constructor));
+ void attr_constructor_2()__attribute__((constructor));
+
+ void attr_destructor_1() __attribute__((destructor));
+static void attr_destructor_2() __attribute__((destructor));
+
+static void attr_constructor_1() { printf("%s %x\n", __func__, --pod_1); }
+ void attr_constructor_2() { printf("%s %x\n", __func__, --pod_2); }
+
+ void attr_destructor_1() { printf("%s %x\n", __func__, --pod_1); pod_1=0; }
+static void attr_destructor_2() { printf("%s %x\n", __func__, --pod_2); pod_2=0; }
+
+
+/********************************************
+ ** Helpers to test C++ exception handling **
+ ********************************************/
+
+static void exception() { throw 666; }
extern void __ldso_raise_exception();
+
+/**
+ * Main function of LDSO test
+ */
int main(int argc, char **argv)
{
- printf("\nStatic Geekings!\n");
- printf( "================\n");
+ printf("\n");
+ printf("Dynamic-linker test\n");
+ printf("===================\n");
+ printf("\n");
+ printf("Global objects and local static objects of program\n");
+ printf("--------------------------------------------------\n");
+ global_1.global_1();
+ global_2.global_2();
+ local_1()->local_1();
+ local_2()->local_2();
+ printf("pod_1 %x\n", --pod_1);
+ printf("pod_2 %x\n", --pod_2);
+ printf("\n");
+
+ printf("Access shared lib from program\n");
+ printf("------------------------------\n");
+ lib_2_global.lib_2_global();
+ lib_1_local_3()->lib_1_local_3();
+ printf("lib_1_pod_1 %x\n", --pod_1);
int fd = 0;
char buf[2];
- printf("Test read\n");
+ printf("Libc::read:\n");
Libc::read(fd, buf, 2);
- printf("Static object in funcion ... ");
- Link::static_function_object();
-
- printf("Shared library function call ...");
- Link::dynamic_link_test();
-
- printf("Exception during RPC: ");
- try {
- Rom_connection rom("__not_found__");
- }
- catch (...) { printf("good\n"); }
-
- printf("Exception in dynamic binary ... ");
- try {
- __raise_exception();
- }
- catch (...) {
- printf("good (binary)\n");
- }
-
- printf("Exception inter-shared library ... ");
- try {
- Link::raise_exception();
- }
- catch (Rm_session::Region_conflict) {
- printf("good (inter)\n");
- }
-
- printf("Exception from LDSO with explicit catch ... ");
- try {
- __ldso_raise_exception();
- } catch (Genode::Exception) {
- printf("good\n");
- }
-
- /* test libc */
int i = Libc::abs(-10);
- printf("Libc test: abs(-10): %d\n", i);
- printf( "================\n\n");
+ printf("Libc::abs(-10): %d\n", i);
+ printf("\n");
- return 0;
+ printf("Catch exceptions in program\n");
+ printf("---------------------------\n");
+ printf("exception in remote procedure call:\n");
+ try { Rom_connection rom("unknown_file"); }
+ catch (Rom_connection::Rom_connection_failed) { printf("caught\n"); }
+
+ printf("exception in program: ");
+ try { exception(); }
+ catch (int) { printf("caught\n"); }
+
+ printf("exception in shared lib: ");
+ try { lib_1_exception(); }
+ catch (Rm_session::Region_conflict) { printf("caught\n"); }
+
+ printf("exception in dynamic linker: ");
+ try { __ldso_raise_exception(); }
+ catch (Genode::Exception) { printf("caught\n"); }
+ printf("\n");
+
+ lib_1_test();
+
+ /* test if return value is propagated correctly by dynamic linker */
+ return 123;
}
diff --git a/libports/src/test/ldso/target.mk b/libports/src/test/ldso/target.mk
index b8d5c3184..3ae157c5c 100644
--- a/libports/src/test/ldso/target.mk
+++ b/libports/src/test/ldso/target.mk
@@ -1,4 +1,4 @@
SRC_CC = main.cc
TARGET = test-ldso
-LIBS = test-ldso libc libm
+LIBS = test-ldso_lib_1 test-ldso_lib_2 libc libm
INC_DIR += $(REP_DIR)/src/test/ldso/include
diff --git a/os/run/ldso.run b/os/run/ldso.run
index ced64d387..7c523f1f8 100644
--- a/os/run/ldso.run
+++ b/os/run/ldso.run
@@ -22,33 +22,94 @@ install_config {
}
-build_boot_image "core init test-ldso test-ldso.lib.so test-ldso2.lib.so libc.lib.so libm.lib.so ld.lib.so"
+build_boot_image "core init test-ldso test-ldso_lib_1.lib.so test-ldso_lib_2.lib.so libc.lib.so libm.lib.so ld.lib.so"
append qemu_args "-nographic -m 64"
-run_genode_until "child exited with exit value 0.*\n" 10
+run_genode_until "child exited with exit value 123.*\n" 10
# pay only attention to the output of init and its children
grep_output {^\[init }
compare_output_to {
- [init -> test-ldso]
- [init -> test-ldso] Static Geekings!
- [init -> test-ldso] ================
- [init -> test-ldso] Test read
- [init -> test-ldso] no plugin found for read(0)
- [init -> test-ldso] Static object in funcion ... a: aaaaaaaa b: bbbbbbbb c: cccccccc 6: 00000666
- [init -> test-ldso] Shared library function call ...good
- [init -> test-ldso] Ctor in shared lib ... a: aaaaaaaa b: bbbbbbbb c: cccccccc 6: 00000666
- [init -> test-ldso] Exception in shared lib ... good (library)
- [init -> test-ldso] Cross library exception ... good (cross library)
- [init -> test-ldso] Exception during RPC: Could not open file "__not_found__"
- [init -> test-ldso] good
- [init -> test-ldso] Exception in dynamic binary ... good (binary)
- [init -> test-ldso] Exception inter-shared library ... good (inter)
- [init -> test-ldso] Exception from LDSO with explicit catch ... good
- [init -> test-ldso] Libc test: abs(-10): 10
- [init -> test-ldso] ================
- [init -> test-ldso]
+[init -> test-ldso] Lib_2_global 11223343
+[init -> test-ldso] Lib_1_global_1 5060707
+[init -> test-ldso] Lib_1_global_2 1020303
+[init -> test-ldso] lib_1_attr_constructor_2 4030200f
+[init -> test-ldso] lib_1_attr_constructor_1 8070604f
+[init -> test-ldso] Global_1 5060707
+[init -> test-ldso] Global_2 1020303
+[init -> test-ldso] attr_constructor_2 4030200f
+[init -> test-ldso] attr_constructor_1 8070604f
+[init -> test-ldso]
+[init -> test-ldso] Dynamic-linker test
+[init -> test-ldso] ===================
+[init -> test-ldso]
+[init -> test-ldso] Global objects and local static objects of program
+[init -> test-ldso] --------------------------------------------------
+[init -> test-ldso] global_1 5060706
+[init -> test-ldso] global_2 1020302
+[init -> test-ldso] Local_1 5060707f
+[init -> test-ldso] local_1 5060707e
+[init -> test-ldso] Local_2 1020303f
+[init -> test-ldso] local_2 1020303e
+[init -> test-ldso] pod_1 8070604e
+[init -> test-ldso] pod_2 4030200e
+[init -> test-ldso]
+[init -> test-ldso] Access shared lib from program
+[init -> test-ldso] ------------------------------
+[init -> test-ldso] lib_2_global 11223342
+[init -> test-ldso] Lib_1_local_3 12345677
+[init -> test-ldso] lib_1_local_3 12345676
+[init -> test-ldso] lib_1_pod_1 8070604d
+[init -> test-ldso] Libc::read:
+[init -> test-ldso] no plugin found for read(0)
+[init -> test-ldso] Libc::abs(-10): 10
+[init -> test-ldso]
+[init -> test-ldso] Catch exceptions in program
+[init -> test-ldso] ---------------------------
+[init -> test-ldso] exception in remote procedure call:
+[init -> test-ldso] Could not open file "unknown_file"
+[init -> test-ldso] caught
+[init -> test-ldso] exception in program: caught
+[init -> test-ldso] exception in shared lib: caught
+[init -> test-ldso] exception in dynamic linker: caught
+[init -> test-ldso]
+[init -> test-ldso] global objects and local static objects of shared lib
+[init -> test-ldso] -----------------------------------------------------
+[init -> test-ldso] lib_1_global_1 5060706
+[init -> test-ldso] lib_1_global_2 1020302
+[init -> test-ldso] Lib_1_local_1 5060707f
+[init -> test-ldso] lib_1_local_1 5060707e
+[init -> test-ldso] Lib_1_local_2 1020303f
+[init -> test-ldso] lib_1_local_2 1020303e
+[init -> test-ldso] lib_1_pod_1 8070604e
+[init -> test-ldso] lib_1_pod_2 4030200e
+[init -> test-ldso]
+[init -> test-ldso] Access shared lib from another shared lib
+[init -> test-ldso] -----------------------------------------
+[init -> test-ldso] lib_2_global 11223341
+[init -> test-ldso] Lib_2_local 55667787
+[init -> test-ldso] lib_2_local 55667786
+[init -> test-ldso] lib_2_pod_1 87654320
+[init -> test-ldso]
+[init -> test-ldso] Catch exceptions in shared lib
+[init -> test-ldso] ------------------------------
+[init -> test-ldso] exception in lib: caught
+[init -> test-ldso] exception in another shared lib: caught
+[init -> test-ldso]
+[init -> test-ldso] ~Lib_2_local 55667785
+[init -> test-ldso] ~Lib_1_local_2 1020303d
+[init -> test-ldso] ~Lib_1_local_1 5060707d
+[init -> test-ldso] ~Lib_1_local_3 12345675
+[init -> test-ldso] ~Local_2 1020303d
+[init -> test-ldso] ~Local_1 5060707d
+[init -> test-ldso] attr_destructor_2 4030200d
+[init -> test-ldso] attr_destructor_1 8070604c
+[init -> test-ldso] ~Global_2 1020301
+[init -> test-ldso] ~Global_1 5060705
+[init -> test-ldso] ~Lib_1_global_2 1020301
+[init -> test-ldso] ~Lib_1_global_1 5060705
+[init -> test-ldso] ~Lib_2_global 11223340
}