1 /* 2 * Copyright 2016, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <err.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 22 #include <limits> 23 #include <thread> 24 25 #include <android-base/file.h> 26 #include <android-base/logging.h> 27 #include <android-base/parseint.h> 28 #include <android-base/unique_fd.h> 29 #include <debuggerd/client.h> 30 #include <procinfo/process.h> 31 #include "util.h" 32 33 using android::base::unique_fd; 34 35 static void usage(int exit_code) { 36 fprintf(stderr, "usage: debuggerd [-b] PID\n"); 37 fprintf(stderr, "\n"); 38 fprintf(stderr, "-b, --backtrace just a backtrace rather than a full tombstone\n"); 39 _exit(exit_code); 40 } 41 42 static std::thread spawn_redirect_thread(unique_fd fd) { 43 return std::thread([fd{ std::move(fd) }]() { 44 while (true) { 45 char buf[BUFSIZ]; 46 ssize_t rc = TEMP_FAILURE_RETRY(read(fd.get(), buf, sizeof(buf))); 47 if (rc <= 0) { 48 return; 49 } 50 51 if (!android::base::WriteFully(STDOUT_FILENO, buf, rc)) { 52 return; 53 } 54 } 55 }); 56 } 57 58 int main(int argc, char* argv[]) { 59 if (argc <= 1) usage(0); 60 if (argc > 3) usage(1); 61 if (argc == 3 && strcmp(argv[1], "-b") != 0 && strcmp(argv[1], "--backtrace") != 0) usage(1); 62 bool backtrace_only = argc == 3; 63 64 pid_t pid; 65 if (!android::base::ParseInt(argv[argc - 1], &pid, 1, std::numeric_limits<pid_t>::max())) { 66 usage(1); 67 } 68 69 if (getuid() != 0) { 70 errx(1, "root is required"); 71 } 72 73 // Check to see if the process exists and that we can actually send a signal to it. 74 android::procinfo::ProcessInfo proc_info; 75 if (!android::procinfo::GetProcessInfo(pid, &proc_info)) { 76 err(1, "failed to fetch info for process %d", pid); 77 } 78 79 if (proc_info.state == android::procinfo::kProcessStateZombie) { 80 errx(1, "process %d is a zombie", pid); 81 } 82 83 if (kill(pid, 0) != 0) { 84 err(1, "cannot send signal to process %d", pid); 85 } 86 87 unique_fd piperead, pipewrite; 88 if (!Pipe(&piperead, &pipewrite)) { 89 err(1, "failed to create pipe"); 90 } 91 92 std::thread redirect_thread = spawn_redirect_thread(std::move(piperead)); 93 if (!debuggerd_trigger_dump(pid, backtrace_only ? kDebuggerdNativeBacktrace : kDebuggerdTombstone, 94 0, std::move(pipewrite))) { 95 redirect_thread.join(); 96 errx(1, "failed to dump process %d", pid); 97 } 98 99 redirect_thread.join(); 100 return 0; 101 } 102