xref: /aosp_15_r20/bionic/tests/libs/atexit_testlib.cpp (revision 8d67ca893c1523eb926b9080dbe4e2ffd2a27ba1)
1*8d67ca89SAndroid Build Coastguard Worker /*
2*8d67ca89SAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*8d67ca89SAndroid Build Coastguard Worker  *
4*8d67ca89SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*8d67ca89SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*8d67ca89SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*8d67ca89SAndroid Build Coastguard Worker  *
8*8d67ca89SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*8d67ca89SAndroid Build Coastguard Worker  *
10*8d67ca89SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*8d67ca89SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*8d67ca89SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8d67ca89SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*8d67ca89SAndroid Build Coastguard Worker  * limitations under the License.
15*8d67ca89SAndroid Build Coastguard Worker  */
16*8d67ca89SAndroid Build Coastguard Worker #include <stdio.h>
17*8d67ca89SAndroid Build Coastguard Worker #include <stdlib.h>
18*8d67ca89SAndroid Build Coastguard Worker 
19*8d67ca89SAndroid Build Coastguard Worker #include <string>
20*8d67ca89SAndroid Build Coastguard Worker 
21*8d67ca89SAndroid Build Coastguard Worker // use external control number from main test
22*8d67ca89SAndroid Build Coastguard Worker static std::string* atexit_sequence = nullptr;
23*8d67ca89SAndroid Build Coastguard Worker static bool* atexit_valid_this_in_static_dtor = nullptr;
24*8d67ca89SAndroid Build Coastguard Worker static bool* atexit_attr_dtor_called = nullptr;
25*8d67ca89SAndroid Build Coastguard Worker 
26*8d67ca89SAndroid Build Coastguard Worker static int cxx_ctor_called = 0;
27*8d67ca89SAndroid Build Coastguard Worker static int attr_ctor_called = 0;
28*8d67ca89SAndroid Build Coastguard Worker 
29*8d67ca89SAndroid Build Coastguard Worker static class AtExitStaticClass {
30*8d67ca89SAndroid Build Coastguard Worker  public:
AtExitStaticClass()31*8d67ca89SAndroid Build Coastguard Worker   AtExitStaticClass() {
32*8d67ca89SAndroid Build Coastguard Worker     expected_this = this;
33*8d67ca89SAndroid Build Coastguard Worker     cxx_ctor_called = 1;
34*8d67ca89SAndroid Build Coastguard Worker   }
~AtExitStaticClass()35*8d67ca89SAndroid Build Coastguard Worker   ~AtExitStaticClass() {
36*8d67ca89SAndroid Build Coastguard Worker     if (atexit_valid_this_in_static_dtor) {
37*8d67ca89SAndroid Build Coastguard Worker       *atexit_valid_this_in_static_dtor = (expected_this == this);
38*8d67ca89SAndroid Build Coastguard Worker     }
39*8d67ca89SAndroid Build Coastguard Worker   }
40*8d67ca89SAndroid Build Coastguard Worker  private:
41*8d67ca89SAndroid Build Coastguard Worker   static const AtExitStaticClass* expected_this;
42*8d67ca89SAndroid Build Coastguard Worker 
43*8d67ca89SAndroid Build Coastguard Worker } static_obj;
44*8d67ca89SAndroid Build Coastguard Worker 
45*8d67ca89SAndroid Build Coastguard Worker const AtExitStaticClass* AtExitStaticClass::expected_this = nullptr;
46*8d67ca89SAndroid Build Coastguard Worker 
47*8d67ca89SAndroid Build Coastguard Worker // 4
atexit_handler_from_atexit_from_atexit2()48*8d67ca89SAndroid Build Coastguard Worker static void atexit_handler_from_atexit_from_atexit2() {
49*8d67ca89SAndroid Build Coastguard Worker   *atexit_sequence += " on";
50*8d67ca89SAndroid Build Coastguard Worker }
51*8d67ca89SAndroid Build Coastguard Worker 
52*8d67ca89SAndroid Build Coastguard Worker // 3
atexit_handler_from_atexit_from_atexit1()53*8d67ca89SAndroid Build Coastguard Worker static void atexit_handler_from_atexit_from_atexit1() {
54*8d67ca89SAndroid Build Coastguard Worker   *atexit_sequence += " sat";
55*8d67ca89SAndroid Build Coastguard Worker }
56*8d67ca89SAndroid Build Coastguard Worker 
57*8d67ca89SAndroid Build Coastguard Worker // 2
atexit_handler_from_atexit()58*8d67ca89SAndroid Build Coastguard Worker static void atexit_handler_from_atexit() {
59*8d67ca89SAndroid Build Coastguard Worker   *atexit_sequence += " Dumpty";
60*8d67ca89SAndroid Build Coastguard Worker   // register 2 others
61*8d67ca89SAndroid Build Coastguard Worker   atexit(atexit_handler_from_atexit_from_atexit2);
62*8d67ca89SAndroid Build Coastguard Worker   atexit(atexit_handler_from_atexit_from_atexit1);
63*8d67ca89SAndroid Build Coastguard Worker }
64*8d67ca89SAndroid Build Coastguard Worker 
65*8d67ca89SAndroid Build Coastguard Worker // 1
atexit_handler_with_atexit()66*8d67ca89SAndroid Build Coastguard Worker static void atexit_handler_with_atexit() {
67*8d67ca89SAndroid Build Coastguard Worker   *atexit_sequence += "Humpty";
68*8d67ca89SAndroid Build Coastguard Worker   atexit(atexit_handler_from_atexit);
69*8d67ca89SAndroid Build Coastguard Worker }
70*8d67ca89SAndroid Build Coastguard Worker 
71*8d67ca89SAndroid Build Coastguard Worker // last
atexit_handler_regular()72*8d67ca89SAndroid Build Coastguard Worker static void atexit_handler_regular() {
73*8d67ca89SAndroid Build Coastguard Worker   *atexit_sequence += " a wall";
74*8d67ca89SAndroid Build Coastguard Worker }
75*8d67ca89SAndroid Build Coastguard Worker 
76*8d67ca89SAndroid Build Coastguard Worker // attribute c-tor and d-tor
atexit_attr_ctor()77*8d67ca89SAndroid Build Coastguard Worker static void __attribute__((constructor)) atexit_attr_ctor() {
78*8d67ca89SAndroid Build Coastguard Worker   attr_ctor_called = 1;
79*8d67ca89SAndroid Build Coastguard Worker }
80*8d67ca89SAndroid Build Coastguard Worker 
atexit_attr_dtor()81*8d67ca89SAndroid Build Coastguard Worker static void __attribute__((destructor)) atexit_attr_dtor() {
82*8d67ca89SAndroid Build Coastguard Worker   if (atexit_attr_dtor_called) {
83*8d67ca89SAndroid Build Coastguard Worker     *atexit_attr_dtor_called = true;
84*8d67ca89SAndroid Build Coastguard Worker   }
85*8d67ca89SAndroid Build Coastguard Worker }
86*8d67ca89SAndroid Build Coastguard Worker 
register_atexit(std::string * sequence,bool * valid_this_in_static_dtor,bool * attr_dtor_called)87*8d67ca89SAndroid Build Coastguard Worker extern "C" void register_atexit(std::string* sequence, bool* valid_this_in_static_dtor, bool* attr_dtor_called) {
88*8d67ca89SAndroid Build Coastguard Worker   atexit_sequence = sequence;
89*8d67ca89SAndroid Build Coastguard Worker   atexit_valid_this_in_static_dtor = valid_this_in_static_dtor;
90*8d67ca89SAndroid Build Coastguard Worker   atexit_attr_dtor_called = attr_dtor_called;
91*8d67ca89SAndroid Build Coastguard Worker   atexit(atexit_handler_regular);
92*8d67ca89SAndroid Build Coastguard Worker   atexit(atexit_handler_with_atexit);
93*8d67ca89SAndroid Build Coastguard Worker }
94*8d67ca89SAndroid Build Coastguard Worker 
get_cxx_ctor_called()95*8d67ca89SAndroid Build Coastguard Worker extern "C" int get_cxx_ctor_called() {
96*8d67ca89SAndroid Build Coastguard Worker   return cxx_ctor_called;
97*8d67ca89SAndroid Build Coastguard Worker }
98*8d67ca89SAndroid Build Coastguard Worker 
get_attr_ctor_called()99*8d67ca89SAndroid Build Coastguard Worker extern "C" int get_attr_ctor_called() {
100*8d67ca89SAndroid Build Coastguard Worker   return attr_ctor_called;
101*8d67ca89SAndroid Build Coastguard Worker }
102*8d67ca89SAndroid Build Coastguard Worker 
103