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 25typedef 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 32int 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 = ℘ 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 82int 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