• 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 
26 #if defined(DEBUG_CRASH_LOCAL_HANDLER)
27 #include "dfx_signal_local_handler.h"
28 #endif
29 
30 static const std::string DUMP_STACK_TAG_USAGE = "Usage:";
31 static const std::string DUMP_STACK_TAG_FAILED = "Failed:";
32 static constexpr int WAIT_GET_KERNEL_STACK_TIMEOUT = 1000; // 1000 : time out 1000 ms
33 
PrintCommandHelp()34 static void PrintCommandHelp()
35 {
36     printf("%s\n", DUMP_STACK_TAG_USAGE.c_str());
37     printf("-p pid -t tid    dump the stacktrace of the thread with given tid.\n");
38     printf("-p pid    dump the stacktrace of all the threads with given pid.\n");
39     printf("-T timeout(ms)     dump in the timeout.\n");
40 }
41 
PrintCommandFailed()42 static void PrintCommandFailed()
43 {
44     printf("%s\npid and tid must > 0 and timeout must > 1000.\n", DUMP_STACK_TAG_FAILED.c_str());
45 }
46 
ParseParamters(int argc,char * argv[],int32_t & pid,int32_t & tid,int & timeout)47 static int ParseParamters(int argc, char *argv[], int32_t &pid, int32_t &tid, int &timeout)
48 {
49     int ret = 0;
50     if (argc <= 1) {
51         return ret;
52     }
53     DFXLOGD("[%{public}d]: argc: %{public}d, argv1: %{public}s", __LINE__, argc, argv[1]);
54 
55     int optRet;
56     const char *optString = "p:t:T:";
57     while ((optRet = getopt(argc, argv, optString)) != -1) {
58         if (optarg == nullptr) {
59             continue;
60         }
61         switch (optRet) {
62             case 'p':
63                 if (atoi(optarg) > 0) {
64                     ret = 1;
65                     pid = atoi(optarg);
66                 } else {
67                     ret = -1;
68                     PrintCommandFailed();
69                 }
70                 break;
71             case 't':
72                 if (atoi(optarg) > 0) {
73                     tid = atoi(optarg);
74                 } else {
75                     ret = -1;
76                     PrintCommandFailed();
77                 }
78                 break;
79             case 'T':
80                 if (atoi(optarg) > WAIT_GET_KERNEL_STACK_TIMEOUT) {
81                     timeout = atoi(optarg);
82                 } else {
83                     ret = -1;
84                     PrintCommandFailed();
85                 }
86                 break;
87             default:
88                 ret = 0;
89                 break;
90         }
91     }
92 
93     if (ret == 0) {
94         PrintCommandHelp();
95     }
96     return ret;
97 }
98 
main(int argc,char * argv[])99 int main(int argc, char *argv[])
100 {
101 #if defined(DEBUG_CRASH_LOCAL_HANDLER)
102     DFX_InstallLocalSignalHandler();
103 #endif
104 
105     int32_t pid = 0;
106     int32_t tid = 0;
107     int timeout = 3000;
108 
109     alarm(DUMPCATCHER_TIMEOUT);
110     setsid();
111 
112     if (ParseParamters(argc, argv, pid, tid, timeout) <= 0) {
113         return 0;
114     }
115 
116     DFXLOGD("pid: %{public}d, tid: %{public}d, timeout: %{public}d", pid, tid, timeout);
117     OHOS::HiviewDFX::DumpCatcher::GetInstance().Dump(pid, tid, timeout);
118     return 0;
119 }
120