1*00c7fec1SAndroid Build Coastguard Worker /*
2*00c7fec1SAndroid Build Coastguard Worker * Copyright 2016, The Android Open Source Project
3*00c7fec1SAndroid Build Coastguard Worker *
4*00c7fec1SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*00c7fec1SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*00c7fec1SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*00c7fec1SAndroid Build Coastguard Worker *
8*00c7fec1SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*00c7fec1SAndroid Build Coastguard Worker *
10*00c7fec1SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*00c7fec1SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*00c7fec1SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*00c7fec1SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*00c7fec1SAndroid Build Coastguard Worker * limitations under the License.
15*00c7fec1SAndroid Build Coastguard Worker */
16*00c7fec1SAndroid Build Coastguard Worker
17*00c7fec1SAndroid Build Coastguard Worker #include <err.h>
18*00c7fec1SAndroid Build Coastguard Worker #include <stdio.h>
19*00c7fec1SAndroid Build Coastguard Worker #include <stdlib.h>
20*00c7fec1SAndroid Build Coastguard Worker #include <string.h>
21*00c7fec1SAndroid Build Coastguard Worker
22*00c7fec1SAndroid Build Coastguard Worker #include <limits>
23*00c7fec1SAndroid Build Coastguard Worker #include <string_view>
24*00c7fec1SAndroid Build Coastguard Worker #include <thread>
25*00c7fec1SAndroid Build Coastguard Worker
26*00c7fec1SAndroid Build Coastguard Worker #include <android-base/logging.h>
27*00c7fec1SAndroid Build Coastguard Worker #include <android-base/parseint.h>
28*00c7fec1SAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
29*00c7fec1SAndroid Build Coastguard Worker #include <debuggerd/client.h>
30*00c7fec1SAndroid Build Coastguard Worker #include <processgroup/processgroup.h>
31*00c7fec1SAndroid Build Coastguard Worker #include <procinfo/process.h>
32*00c7fec1SAndroid Build Coastguard Worker #include "util.h"
33*00c7fec1SAndroid Build Coastguard Worker
34*00c7fec1SAndroid Build Coastguard Worker using android::base::unique_fd;
35*00c7fec1SAndroid Build Coastguard Worker
usage(int exit_code)36*00c7fec1SAndroid Build Coastguard Worker static void usage(int exit_code) {
37*00c7fec1SAndroid Build Coastguard Worker fprintf(stderr, "usage: debuggerd [-bj] PID\n");
38*00c7fec1SAndroid Build Coastguard Worker fprintf(stderr, "\n");
39*00c7fec1SAndroid Build Coastguard Worker fprintf(stderr, "-b, --backtrace just a backtrace rather than a full tombstone\n");
40*00c7fec1SAndroid Build Coastguard Worker fprintf(stderr, "-j collect java traces\n");
41*00c7fec1SAndroid Build Coastguard Worker _exit(exit_code);
42*00c7fec1SAndroid Build Coastguard Worker }
43*00c7fec1SAndroid Build Coastguard Worker
main(int argc,char * argv[])44*00c7fec1SAndroid Build Coastguard Worker int main(int argc, char* argv[]) {
45*00c7fec1SAndroid Build Coastguard Worker if (argc <= 1) usage(0);
46*00c7fec1SAndroid Build Coastguard Worker if (argc > 3) usage(1);
47*00c7fec1SAndroid Build Coastguard Worker
48*00c7fec1SAndroid Build Coastguard Worker DebuggerdDumpType dump_type = kDebuggerdTombstone;
49*00c7fec1SAndroid Build Coastguard Worker
50*00c7fec1SAndroid Build Coastguard Worker if (argc == 3) {
51*00c7fec1SAndroid Build Coastguard Worker std::string_view flag = argv[1];
52*00c7fec1SAndroid Build Coastguard Worker if (flag == "-b" || flag == "--backtrace") {
53*00c7fec1SAndroid Build Coastguard Worker dump_type = kDebuggerdNativeBacktrace;
54*00c7fec1SAndroid Build Coastguard Worker } else if (flag == "-j") {
55*00c7fec1SAndroid Build Coastguard Worker dump_type = kDebuggerdJavaBacktrace;
56*00c7fec1SAndroid Build Coastguard Worker } else {
57*00c7fec1SAndroid Build Coastguard Worker usage(1);
58*00c7fec1SAndroid Build Coastguard Worker }
59*00c7fec1SAndroid Build Coastguard Worker }
60*00c7fec1SAndroid Build Coastguard Worker
61*00c7fec1SAndroid Build Coastguard Worker pid_t pid;
62*00c7fec1SAndroid Build Coastguard Worker if (!android::base::ParseInt(argv[argc - 1], &pid, 1, std::numeric_limits<pid_t>::max())) {
63*00c7fec1SAndroid Build Coastguard Worker usage(1);
64*00c7fec1SAndroid Build Coastguard Worker }
65*00c7fec1SAndroid Build Coastguard Worker
66*00c7fec1SAndroid Build Coastguard Worker if (getuid() != 0) {
67*00c7fec1SAndroid Build Coastguard Worker errx(1, "root is required");
68*00c7fec1SAndroid Build Coastguard Worker }
69*00c7fec1SAndroid Build Coastguard Worker
70*00c7fec1SAndroid Build Coastguard Worker // Check to see if the process exists and that we can actually send a signal to it.
71*00c7fec1SAndroid Build Coastguard Worker android::procinfo::ProcessInfo proc_info;
72*00c7fec1SAndroid Build Coastguard Worker if (!android::procinfo::GetProcessInfo(pid, &proc_info)) {
73*00c7fec1SAndroid Build Coastguard Worker err(1, "failed to fetch info for process %d", pid);
74*00c7fec1SAndroid Build Coastguard Worker }
75*00c7fec1SAndroid Build Coastguard Worker
76*00c7fec1SAndroid Build Coastguard Worker if (proc_info.state == android::procinfo::kProcessStateZombie) {
77*00c7fec1SAndroid Build Coastguard Worker errx(1, "process %d is a zombie", pid);
78*00c7fec1SAndroid Build Coastguard Worker }
79*00c7fec1SAndroid Build Coastguard Worker
80*00c7fec1SAndroid Build Coastguard Worker // Send a signal to the main thread pid, not a side thread. The signal
81*00c7fec1SAndroid Build Coastguard Worker // handler always sets the crashing tid to the main thread pid when sent this
82*00c7fec1SAndroid Build Coastguard Worker // signal. This is to avoid a problem where the signal is sent to a process,
83*00c7fec1SAndroid Build Coastguard Worker // but happens on a side thread and the intercept mismatches since it
84*00c7fec1SAndroid Build Coastguard Worker // is looking for the main thread pid, not the tid of this random thread.
85*00c7fec1SAndroid Build Coastguard Worker // See b/194346289 for extra details.
86*00c7fec1SAndroid Build Coastguard Worker if (kill(proc_info.pid, 0) != 0) {
87*00c7fec1SAndroid Build Coastguard Worker if (pid == proc_info.pid) {
88*00c7fec1SAndroid Build Coastguard Worker err(1, "cannot send signal to process %d", pid);
89*00c7fec1SAndroid Build Coastguard Worker } else {
90*00c7fec1SAndroid Build Coastguard Worker err(1, "cannot send signal to main thread %d (requested thread %d)", proc_info.pid, pid);
91*00c7fec1SAndroid Build Coastguard Worker }
92*00c7fec1SAndroid Build Coastguard Worker }
93*00c7fec1SAndroid Build Coastguard Worker
94*00c7fec1SAndroid Build Coastguard Worker // unfreeze if pid is frozen.
95*00c7fec1SAndroid Build Coastguard Worker SetProcessProfiles(proc_info.uid, proc_info.pid, {"Unfrozen"});
96*00c7fec1SAndroid Build Coastguard Worker // we don't restore the frozen state as this is considered a benign change.
97*00c7fec1SAndroid Build Coastguard Worker
98*00c7fec1SAndroid Build Coastguard Worker unique_fd output_fd(fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 0));
99*00c7fec1SAndroid Build Coastguard Worker if (output_fd.get() == -1) {
100*00c7fec1SAndroid Build Coastguard Worker err(1, "failed to fcntl dup stdout");
101*00c7fec1SAndroid Build Coastguard Worker }
102*00c7fec1SAndroid Build Coastguard Worker if (!debuggerd_trigger_dump(proc_info.pid, dump_type, 0, std::move(output_fd))) {
103*00c7fec1SAndroid Build Coastguard Worker if (pid == proc_info.pid) {
104*00c7fec1SAndroid Build Coastguard Worker errx(1, "failed to dump process %d", pid);
105*00c7fec1SAndroid Build Coastguard Worker } else {
106*00c7fec1SAndroid Build Coastguard Worker errx(1, "failed to dump main thread %d (requested thread %d)", proc_info.pid, pid);
107*00c7fec1SAndroid Build Coastguard Worker }
108*00c7fec1SAndroid Build Coastguard Worker }
109*00c7fec1SAndroid Build Coastguard Worker
110*00c7fec1SAndroid Build Coastguard Worker return 0;
111*00c7fec1SAndroid Build Coastguard Worker }
112