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