• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 <cstdio>
17 #include <cstdlib>
18 #include <securec.h>
19 #include <string>
20 #include <unistd.h>
21 #include <getopt.h>
22 #include "dfx_define.h"
23 #include "dfx_log.h"
24 #include "dump_catcher.h"
25 #include "faultloggerd_client.h"
26 
27 #if defined(DEBUG_CRASH_LOCAL_HANDLER)
28 #include "dfx_signal_local_handler.h"
29 #endif
30 
31 static const std::string DUMP_STACK_TAG_USAGE = "Usage:";
32 static const std::string DUMP_STACK_TAG_FAILED = "Failed:";
33 static constexpr int WAIT_GET_KERNEL_STACK_TIMEOUT = 1000; // 1000 : time out 1000 ms
34 static constexpr int SAVE_CORE_DUMP_TIMEOUT = 10000; //  time out 10000 ms
35 
PrintCommandHelp()36 static void PrintCommandHelp()
37 {
38     printf("%s\n", DUMP_STACK_TAG_USAGE.c_str());
39     printf("-p pid -t tid    dump the stacktrace of the thread with given tid.\n");
40     printf("-p pid    dump the stacktrace of all the threads with given pid.\n");
41     printf("-T timeout(ms)     dump in the timeout.\n");
42 }
43 
PrintCommandFailed()44 static void PrintCommandFailed()
45 {
46     printf("%s\npid and tid must > 0 and timeout must > 1000.\n", DUMP_STACK_TAG_FAILED.c_str());
47 }
48 
49 
GetIdFromArgs(char * optarg,int32_t & id)50 static int GetIdFromArgs(char *optarg, int32_t &id)
51 {
52     int ret = 0;
53 
54     if (atoi(optarg) > 0) {
55         ret = 1;
56         id = atoi(optarg);
57     } else {
58         ret = -1;
59         PrintCommandFailed();
60     }
61 
62     return ret;
63 }
64 
ExecuteCoredumpCmd(std::string subCmd,char * pidChar)65 static int ExecuteCoredumpCmd(std::string subCmd, char* pidChar)
66 {
67     if (atoi(pidChar) <= 0) {
68         printf("pid error, input should like dumpcatcher -c save/cancel pid\n");
69         return -1;
70     }
71     pid_t pid = atoi(pidChar);
72     printf("cmd is -c %s %d \n", subCmd.c_str(), pid);
73     if (subCmd == "save") {
74         SaveCoredumpToFileTimeout(pid, SAVE_CORE_DUMP_TIMEOUT);
75         return 0;
76     } else if (subCmd == "cancel") {
77         CancelCoredump(pid);
78         return 0;
79     } else {
80         printf("input error coredump cmd!\n");
81         return -1;
82     }
83 }
84 
ParseParamters(int argc,char * argv[],int32_t & pid,int32_t & tid,int & timeout)85 static int ParseParamters(int argc, char *argv[], int32_t &pid, int32_t &tid, int &timeout)
86 {
87     int ret = 0;
88     if (argc <= 1) {
89         return ret;
90     }
91     DFXLOGD("[%{public}d]: argc: %{public}d, argv1: %{public}s", __LINE__, argc, argv[1]);
92 
93     int optRet;
94     const char *optString = "p:t:c:T:";
95     while ((optRet = getopt(argc, argv, optString)) != -1) {
96         if (optarg == nullptr) {
97             continue;
98         }
99         switch (optRet) {
100             case 'p':
101                 ret = GetIdFromArgs(optarg, pid);
102                 break;
103             case 't':
104                 ret = GetIdFromArgs(optarg, tid);
105                 break;
106             case 'c':
107                 if (optind >= argc) {
108                     printf("input error, input should like dumpcatcher -c save/cancel pid\n");
109                     return 0;
110                 }
111                 ExecuteCoredumpCmd(optarg, argv[optind]);
112                 return 0;
113             case 'T':
114                 if (atoi(optarg) > WAIT_GET_KERNEL_STACK_TIMEOUT) {
115                     timeout = atoi(optarg);
116                 } else {
117                     ret = -1;
118                     PrintCommandFailed();
119                 }
120                 break;
121             default:
122                 ret = 0;
123                 break;
124         }
125     }
126 
127     if (ret == 0) {
128         PrintCommandHelp();
129     }
130     return ret;
131 }
132 
main(int argc,char * argv[])133 int main(int argc, char *argv[])
134 {
135 #if defined(DEBUG_CRASH_LOCAL_HANDLER)
136     DFX_InstallLocalSignalHandler();
137 #endif
138 
139     int32_t pid = 0;
140     int32_t tid = 0;
141     int timeout = 3000;
142 
143     alarm(DUMPCATCHER_TIMEOUT);
144     setsid();
145 
146     if (ParseParamters(argc, argv, pid, tid, timeout) <= 0) {
147         return 0;
148     }
149 
150     DFXLOGD("pid: %{public}d, tid: %{public}d, timeout: %{public}d", pid, tid, timeout);
151     OHOS::HiviewDFX::DumpCatcher::GetInstance().Dump(pid, tid, timeout);
152     return 0;
153 }
154