• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <dlfcn.h>
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <sys/wait.h>
21 #include <string.h>
22 #include <errno.h>
23 #include "test.h"
24 
25 typedef void (* ATEXIT_CB)();
26 
27 #define TEST_DSO "/data/tests/libc-test/src/libatexit_dlclose_dso.so"
28 #define ATEXIT_CB_NAME "atexit_cb"
29 #define ATEXIT_WATCHPOINT_NAME "g_watchpoint"
30 #define LIBATEXIT_DLCLOSE_DSO_ABSOLUTE_PATH "/data/tests/libc-test/src/libatexit_dlclose_dso.so"
31 
fork_main(char * exe)32 int fork_main(char *exe)
33 {
34 	char buf[512];
35 	void *handler = NULL;
36 	ATEXIT_CB cb = NULL;
37 	unsigned int *wp_ptr = NULL;
38 	unsigned int wp = 0;
39 
40 	int err = 0;
41 
42 	if(!t_pathrel(buf, sizeof(buf), exe, TEST_DSO)) {
43 		t_error("failed to obtain relative path to " TEST_DSO "\n");
44 		return 1;
45 	}
46 
47 	handler = dlopen(LIBATEXIT_DLCLOSE_DSO_ABSOLUTE_PATH, RTLD_LAZY|RTLD_LOCAL);
48 	if(!handler) {
49 		t_error("dlopen %s failed: %s\n", buf, dlerror());
50 		return 2;
51 	}
52 
53 	cb = (ATEXIT_CB)dlsym(handler, ATEXIT_CB_NAME);
54 	if (!cb) {
55 		t_error("dlsym %s failed: %s\n", ATEXIT_CB_NAME, dlerror());
56 		return 3;
57 	}
58 
59 	wp_ptr = (unsigned int *)dlsym(handler, ATEXIT_WATCHPOINT_NAME);
60 	if (!wp_ptr) {
61 		t_error("dlsym %s failed: %s\n", ATEXIT_WATCHPOINT_NAME, dlerror());
62 		return 3;
63 	}
64 
65 	wp_ptr = &wp;
66 
67 	err = atexit(cb);
68 
69 	if(dlclose( handler)) {
70 		t_error("dlclose failed: %s\n", dlerror());
71 		return 4;
72 	}
73 
74 	if (wp == 0xFFFF) {
75 		t_error("error, atexit callback called");
76 		return 5;
77 	}
78 
79 	return 0;
80 }
81 
main(int argc,char * argv[])82 int main(int argc, char *argv[])
83 {
84 	pid_t pid, w;
85 	int err;
86 	int wstatus;
87 
88 	pid = fork();
89 	if (pid == 0) { // child process
90 		return fork_main(argv[0]);
91 	} else if (pid > 0) { // parent process
92 		w = waitpid(pid, &wstatus, 0);
93 		if (w == -1) {
94 			t_error("wait for child process failed");
95 			return 1;
96 		}
97 
98 		if (WIFEXITED(wstatus)) {
99 			err = WEXITSTATUS(wstatus);
100 			t_error("exited with status=%d\n", err);
101 			return err;
102 		} else if (WIFSIGNALED(wstatus)) {
103 			t_error("killed by signal %d\n", WTERMSIG(wstatus));
104 			return 9;
105 		} else if (WIFSTOPPED(wstatus)) {
106 			t_error("stopped by signal %d\n", WSTOPSIG(wstatus));
107 			return 9;
108 		} else {
109 			t_error("stopped by signal %d\n", WSTOPSIG(wstatus));
110 			return 9;
111 		}
112 	} else {
113 		t_error("fork failed: %s\n", strerror(errno));
114 		return 1;
115 	}
116 }
117 
118