• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
40 typedef int (*KillFunc)(pid_t pid, int sig);
41 typedef __attribute__((noreturn)) void (*ExitFunc)(int code);
42 static KillFunc g_hookedKill = NULL;
43 static ExitFunc g_hookedExit = NULL;
44 static ExitFunc g_hookedExitEx = NULL;
45 static bool g_abortWhenExit = false;
46 
InitExitHook(void)47 static 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 
kill(pid_t pid,int sig)58 int kill(pid_t pid, int sig)
59 {
60     LOGF("%d send signal(%d) to %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         LOGE("hooked kill is NULL?\n");
69         return syscall(SYS_kill, pid, sig);
70     }
71     return g_hookedKill(pid, sig);
72 }
73 
exit(int code)74 void exit(int code)
75 {
76     LOGF("%d call exit with code %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 
_exit(int code)90 void _exit(int code)
91 {
92     LOGF("%d call exit with code %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 
106 GEN_HOOK_FUNC(StartHookKillFunction, KillFunc, "kill", g_hookedKill)
107 GEN_HOOK_FUNC(StartHookExitFunction, ExitFunc, "exit", g_hookedExit)
108 GEN_HOOK_FUNC(StartHookExitExFunction, ExitFunc, "_exit", g_hookedExitEx)
109 
StartHookExitFunc(void)110 void StartHookExitFunc(void)
111 {
112     StartHookKillFunction();
113     StartHookExitFunction();
114     StartHookExitExFunction();
115 }
116