1/* 2 * Copyright (c) 2022 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 "dfx_exit_hook.h" 17 18#include <dlfcn.h> 19#include <signal.h> 20#include <stdbool.h> 21#include <stdio.h> 22#include <stdlib.h> 23#include <string.h> 24#include <syscall.h> 25#include <unistd.h> 26 27#include "dfx_log.h" 28#include "dfx_hook_utils.h" 29 30#ifdef LOG_DOMAIN 31#undef LOG_DOMAIN 32#define LOG_DOMAIN 0xD002D11 33#endif 34 35#ifdef LOG_TAG 36#undef LOG_TAG 37#define LOG_TAG "DfxExitHook" 38#endif 39 40typedef int (*KillFunc)(pid_t pid, int sig); 41typedef __attribute__((noreturn)) void (*ExitFunc)(int code); 42static KillFunc g_hookedKill = NULL; 43static ExitFunc g_hookedExit = NULL; 44static ExitFunc g_hookedExitEx = NULL; 45static bool g_abortWhenExit = false; 46 47static void __attribute__((constructor)) InitExitHook(void) 48{ 49 char* str = getenv("ABORT_EXIT"); 50 if (str != NULL && strlen(str) > 0) { 51 printf("AbortExit:%s\n", str); 52 g_abortWhenExit = true; 53 } 54 55 StartHookExitFunc(); 56} 57 58int kill(pid_t pid, int sig) 59{ 60 DFXLOGF("%{public}d send signal(%{public}d) to %{public}d", getpid(), sig, pid); 61 if ((sig == SIGKILL) && (pid == getpid())) { 62 abort(); 63 } else if (sig == SIGKILL) { 64 LogBacktrace(); 65 } 66 67 if (g_hookedKill == NULL) { 68 DFXLOGE("hooked kill is NULL?\n"); 69 return syscall(SYS_kill, pid, sig); 70 } 71 return g_hookedKill(pid, sig); 72} 73 74void exit(int code) 75{ 76 DFXLOGF("%{public}d call exit with code %{public}d", getpid(), code); 77 if (!g_abortWhenExit) { 78 LogBacktrace(); 79 } 80 81 if ((!g_abortWhenExit) && (g_hookedExit != NULL)) { 82 g_hookedExit(code); 83 } else if (g_abortWhenExit) { 84 abort(); 85 } 86 87 quick_exit(code); 88} 89 90void _exit(int code) 91{ 92 DFXLOGF("%{public}d call exit with code %{public}d", getpid(), code); 93 if (!g_abortWhenExit) { 94 LogBacktrace(); 95 } 96 97 if ((!g_abortWhenExit) && (g_hookedExitEx != NULL)) { 98 g_hookedExitEx(code); 99 } else if (g_abortWhenExit) { 100 abort(); 101 } 102 103 quick_exit(code); 104} 105 106GEN_HOOK_FUNC(StartHookKillFunction, KillFunc, "kill", g_hookedKill) 107GEN_HOOK_FUNC(StartHookExitFunction, ExitFunc, "exit", g_hookedExit) 108GEN_HOOK_FUNC(StartHookExitExFunction, ExitFunc, "_exit", g_hookedExitEx) 109 110void StartHookExitFunc(void) 111{ 112 StartHookKillFunction(); 113 StartHookExitFunction(); 114 StartHookExitExFunction(); 115} 116