Jeff Brown | 053b865 | 2012-06-06 16:25:03 -0700 | [diff] [blame] | 1 | /* |
Mark Salyzyn | fca0bd1 | 2013-12-12 12:21:20 -0800 | [diff] [blame] | 2 | * Copyright (C) 2012-2014 The Android Open Source Project |
Jeff Brown | 053b865 | 2012-06-06 16:25:03 -0700 | [diff] [blame] | 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 | |
Brigid Smith | 62ba489 | 2014-06-10 11:53:08 -0700 | [diff] [blame] | 17 | #define LOG_TAG "DEBUG" |
| 18 | |
Josh Gao | c370666 | 2017-08-29 13:08:32 -0700 | [diff] [blame] | 19 | #include "libdebuggerd/tombstone.h" |
| 20 | |
Kévin PETIT | 4bb4772 | 2013-12-18 16:44:24 +0000 | [diff] [blame] | 21 | #include <errno.h> |
Kévin PETIT | 4bb4772 | 2013-12-18 16:44:24 +0000 | [diff] [blame] | 22 | #include <signal.h> |
| 23 | #include <stddef.h> |
| 24 | #include <stdio.h> |
| 25 | #include <stdlib.h> |
Christopher Ferris | bdea3bb | 2021-11-17 01:09:22 +0000 | [diff] [blame^] | 26 | #include <sys/types.h> |
| 27 | #include <unistd.h> |
Jeff Brown | 053b865 | 2012-06-06 16:25:03 -0700 | [diff] [blame] | 28 | |
Christopher Ferris | 6e96403 | 2015-05-15 17:30:21 -0700 | [diff] [blame] | 29 | #include <memory> |
| 30 | #include <string> |
| 31 | |
Josh Gao | 57f58f8 | 2017-03-15 23:23:22 -0700 | [diff] [blame] | 32 | #include <android-base/file.h> |
Josh Gao | 57f58f8 | 2017-03-15 23:23:22 -0700 | [diff] [blame] | 33 | #include <android-base/unique_fd.h> |
| 34 | #include <android/log.h> |
Josh Gao | 618cea3 | 2021-01-26 17:45:43 -0800 | [diff] [blame] | 35 | #include <async_safe/log.h> |
Mark Salyzyn | cfd5b08 | 2016-10-17 14:28:00 -0700 | [diff] [blame] | 36 | #include <log/log.h> |
Mark Salyzyn | ff2dcd9 | 2016-09-28 15:54:45 -0700 | [diff] [blame] | 37 | #include <private/android_filesystem_config.h> |
Josh Gao | 2b2ae0c | 2017-08-21 14:31:17 -0700 | [diff] [blame] | 38 | #include <unwindstack/Memory.h> |
| 39 | #include <unwindstack/Regs.h> |
Christopher Ferris | 60eb197 | 2019-01-15 15:18:43 -0800 | [diff] [blame] | 40 | #include <unwindstack/Unwinder.h> |
Jeff Brown | 053b865 | 2012-06-06 16:25:03 -0700 | [diff] [blame] | 41 | |
Josh Gao | c370666 | 2017-08-29 13:08:32 -0700 | [diff] [blame] | 42 | #include "libdebuggerd/backtrace.h" |
Josh Gao | c370666 | 2017-08-29 13:08:32 -0700 | [diff] [blame] | 43 | #include "libdebuggerd/open_files_list.h" |
Josh Gao | 2b2ae0c | 2017-08-21 14:31:17 -0700 | [diff] [blame] | 44 | #include "libdebuggerd/utility.h" |
Elliott Hughes | a660cb3 | 2020-07-23 15:26:10 -0700 | [diff] [blame] | 45 | #include "util.h" |
Jeff Brown | 053b865 | 2012-06-06 16:25:03 -0700 | [diff] [blame] | 46 | |
Josh Gao | 76e1e30 | 2021-01-26 15:53:11 -0800 | [diff] [blame] | 47 | #include "tombstone.pb.h" |
| 48 | |
Josh Gao | 2b2ae0c | 2017-08-21 14:31:17 -0700 | [diff] [blame] | 49 | using android::base::unique_fd; |
| 50 | |
Elliott Hughes | e1415a5 | 2018-02-15 09:18:21 -0800 | [diff] [blame] | 51 | using namespace std::literals::string_literals; |
| 52 | |
Josh Gao | 76e1e30 | 2021-01-26 15:53:11 -0800 | [diff] [blame] | 53 | void engrave_tombstone_ucontext(int tombstone_fd, int proto_fd, uint64_t abort_msg_address, |
| 54 | siginfo_t* siginfo, ucontext_t* ucontext) { |
Misha Wagner | 39c5b8c | 2019-04-18 16:07:33 +0100 | [diff] [blame] | 55 | pid_t uid = getuid(); |
Josh Gao | e1aa0ca | 2017-03-01 17:23:22 -0800 | [diff] [blame] | 56 | pid_t pid = getpid(); |
| 57 | pid_t tid = gettid(); |
| 58 | |
Josh Gao | e73c932 | 2017-02-08 16:06:26 -0800 | [diff] [blame] | 59 | log_t log; |
| 60 | log.current_tid = tid; |
| 61 | log.crashed_tid = tid; |
| 62 | log.tfd = tombstone_fd; |
| 63 | log.amfd_data = nullptr; |
| 64 | |
Elliott Hughes | a660cb3 | 2020-07-23 15:26:10 -0700 | [diff] [blame] | 65 | std::string thread_name = get_thread_name(tid); |
Josh Gao | 31348a7 | 2021-03-29 21:53:42 -0700 | [diff] [blame] | 66 | std::vector<std::string> command_line = get_command_line(pid); |
Josh Gao | 57f58f8 | 2017-03-15 23:23:22 -0700 | [diff] [blame] | 67 | |
Christopher Ferris | 60eb197 | 2019-01-15 15:18:43 -0800 | [diff] [blame] | 68 | std::unique_ptr<unwindstack::Regs> regs( |
| 69 | unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), ucontext)); |
Josh Gao | e73c932 | 2017-02-08 16:06:26 -0800 | [diff] [blame] | 70 | |
Josh Gao | 76e1e30 | 2021-01-26 15:53:11 -0800 | [diff] [blame] | 71 | std::string selinux_label; |
| 72 | android::base::ReadFileToString("/proc/self/attr/current", &selinux_label); |
| 73 | |
Josh Gao | 2b2ae0c | 2017-08-21 14:31:17 -0700 | [diff] [blame] | 74 | std::map<pid_t, ThreadInfo> threads; |
Elliott Hughes | a660cb3 | 2020-07-23 15:26:10 -0700 | [diff] [blame] | 75 | threads[tid] = ThreadInfo{ |
Josh Gao | 2b2ae0c | 2017-08-21 14:31:17 -0700 | [diff] [blame] | 76 | .registers = std::move(regs), |
Misha Wagner | 39c5b8c | 2019-04-18 16:07:33 +0100 | [diff] [blame] | 77 | .uid = uid, |
Josh Gao | 2b2ae0c | 2017-08-21 14:31:17 -0700 | [diff] [blame] | 78 | .tid = tid, |
Josh Gao | 76e1e30 | 2021-01-26 15:53:11 -0800 | [diff] [blame] | 79 | .thread_name = std::move(thread_name), |
Josh Gao | 2b2ae0c | 2017-08-21 14:31:17 -0700 | [diff] [blame] | 80 | .pid = pid, |
Josh Gao | 31348a7 | 2021-03-29 21:53:42 -0700 | [diff] [blame] | 81 | .command_line = std::move(command_line), |
Josh Gao | 76e1e30 | 2021-01-26 15:53:11 -0800 | [diff] [blame] | 82 | .selinux_label = std::move(selinux_label), |
Josh Gao | 2b2ae0c | 2017-08-21 14:31:17 -0700 | [diff] [blame] | 83 | .siginfo = siginfo, |
| 84 | }; |
Josh Gao | 77b00ed | 2017-05-05 18:11:23 -0700 | [diff] [blame] | 85 | |
Christopher Ferris | b05c472 | 2020-09-23 15:51:46 -0700 | [diff] [blame] | 86 | unwindstack::UnwinderFromPid unwinder(kMaxFrames, pid, unwindstack::Regs::CurrentArch()); |
yidong zhang | cbf7c46 | 2021-06-24 17:51:56 +0800 | [diff] [blame] | 87 | auto process_memory = |
| 88 | unwindstack::Memory::CreateProcessMemoryCached(getpid()); |
| 89 | unwinder.SetProcessMemory(process_memory); |
Christopher Ferris | b05c472 | 2020-09-23 15:51:46 -0700 | [diff] [blame] | 90 | if (!unwinder.Init()) { |
Josh Gao | 618cea3 | 2021-01-26 17:45:43 -0800 | [diff] [blame] | 91 | async_safe_fatal("failed to init unwinder object"); |
Josh Gao | e73c932 | 2017-02-08 16:06:26 -0800 | [diff] [blame] | 92 | } |
Josh Gao | fdc95c9 | 2017-09-13 15:33:39 -0700 | [diff] [blame] | 93 | |
Peter Collingbourne | 843f7e6 | 2020-02-28 19:07:33 -0800 | [diff] [blame] | 94 | ProcessInfo process_info; |
| 95 | process_info.abort_msg_address = abort_msg_address; |
Josh Gao | 76e1e30 | 2021-01-26 15:53:11 -0800 | [diff] [blame] | 96 | engrave_tombstone(unique_fd(dup(tombstone_fd)), unique_fd(dup(proto_fd)), &unwinder, threads, tid, |
| 97 | process_info, nullptr, nullptr); |
Josh Gao | 2b2ae0c | 2017-08-21 14:31:17 -0700 | [diff] [blame] | 98 | } |
| 99 | |
Josh Gao | 76e1e30 | 2021-01-26 15:53:11 -0800 | [diff] [blame] | 100 | void engrave_tombstone(unique_fd output_fd, unique_fd proto_fd, unwindstack::Unwinder* unwinder, |
Josh Gao | 2b2ae0c | 2017-08-21 14:31:17 -0700 | [diff] [blame] | 101 | const std::map<pid_t, ThreadInfo>& threads, pid_t target_thread, |
Peter Collingbourne | 843f7e6 | 2020-02-28 19:07:33 -0800 | [diff] [blame] | 102 | const ProcessInfo& process_info, OpenFilesList* open_files, |
| 103 | std::string* amfd_data) { |
Elliott Hughes | a660cb3 | 2020-07-23 15:26:10 -0700 | [diff] [blame] | 104 | // Don't copy log messages to tombstone unless this is a development device. |
Josh Gao | 76e1e30 | 2021-01-26 15:53:11 -0800 | [diff] [blame] | 105 | Tombstone tombstone; |
| 106 | engrave_tombstone_proto(&tombstone, unwinder, threads, target_thread, process_info, open_files); |
| 107 | |
Josh Gao | 618cea3 | 2021-01-26 17:45:43 -0800 | [diff] [blame] | 108 | if (proto_fd != -1) { |
| 109 | if (!tombstone.SerializeToFileDescriptor(proto_fd.get())) { |
| 110 | async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, "failed to write proto tombstone: %s", |
| 111 | strerror(errno)); |
| 112 | } |
Josh Gao | 76e1e30 | 2021-01-26 15:53:11 -0800 | [diff] [blame] | 113 | } |
Josh Gao | 2b2ae0c | 2017-08-21 14:31:17 -0700 | [diff] [blame] | 114 | |
| 115 | log_t log; |
| 116 | log.current_tid = target_thread; |
| 117 | log.crashed_tid = target_thread; |
| 118 | log.tfd = output_fd.get(); |
| 119 | log.amfd_data = amfd_data; |
| 120 | |
Christopher Ferris | bdea3bb | 2021-11-17 01:09:22 +0000 | [diff] [blame^] | 121 | tombstone_proto_to_text(tombstone, [&log](const std::string& line, bool should_log) { |
| 122 | _LOG(&log, should_log ? logtype::HEADER : logtype::LOGS, "%s\n", line.c_str()); |
| 123 | }); |
Josh Gao | e73c932 | 2017-02-08 16:06:26 -0800 | [diff] [blame] | 124 | } |