blob: 01e9cf69b73108d16d61b2867c42437ed056986d [file] [log] [blame]
Jeff Brown053b8652012-06-06 16:25:03 -07001/*
Mark Salyzynfca0bd12013-12-12 12:21:20 -08002 * Copyright (C) 2012-2014 The Android Open Source Project
Jeff Brown053b8652012-06-06 16:25:03 -07003 *
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 Smith62ba4892014-06-10 11:53:08 -070017#define LOG_TAG "DEBUG"
18
Jeff Brown053b8652012-06-06 16:25:03 -070019#include <dirent.h>
Kévin PETIT4bb47722013-12-18 16:44:24 +000020#include <errno.h>
21#include <fcntl.h>
22#include <inttypes.h>
23#include <signal.h>
24#include <stddef.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
Jeff Brown053b8652012-06-06 16:25:03 -070028#include <sys/ptrace.h>
29#include <sys/stat.h>
Mark Salyzynff2dcd92016-09-28 15:54:45 -070030#include <time.h>
Jeff Brown053b8652012-06-06 16:25:03 -070031
Christopher Ferris6e964032015-05-15 17:30:21 -070032#include <memory>
33#include <string>
34
Josh Gaocbe70cb2016-10-18 18:17:52 -070035#include <android/log.h>
Elliott Hughes4f713192015-12-04 22:00:26 -080036#include <android-base/stringprintf.h>
Christopher Ferris20303f82014-01-10 16:33:16 -080037#include <backtrace/Backtrace.h>
Christopher Ferris46756822014-01-14 20:16:30 -080038#include <backtrace/BacktraceMap.h>
Mark Salyzynff2dcd92016-09-28 15:54:45 -070039#include <cutils/properties.h>
Mark Salyzyncfd5b082016-10-17 14:28:00 -070040#include <log/log.h>
Mark Salyzynff2dcd92016-09-28 15:54:45 -070041#include <log/logprint.h>
42#include <private/android_filesystem_config.h>
Jeff Brown053b8652012-06-06 16:25:03 -070043
Josh Gaocbe70cb2016-10-18 18:17:52 -070044#include "debuggerd/handler.h"
rpcraigf1186f32012-07-19 09:38:06 -040045
Christopher Ferrisa21bd932015-02-27 13:39:47 -080046#include "backtrace.h"
47#include "elf_utils.h"
Jeff Brown053b8652012-06-06 16:25:03 -070048#include "machine.h"
Richard Uhler53fb32f2016-10-28 16:37:33 +010049#include "open_files_list.h"
Jeff Brown053b8652012-06-06 16:25:03 -070050#include "tombstone.h"
Jeff Brown053b8652012-06-06 16:25:03 -070051
Jeff Brown053b8652012-06-06 16:25:03 -070052#define STACK_WORDS 16
53
54#define MAX_TOMBSTONES 10
55#define TOMBSTONE_DIR "/data/tombstones"
Kévin PETIT4bb47722013-12-18 16:44:24 +000056#define TOMBSTONE_TEMPLATE (TOMBSTONE_DIR"/tombstone_%02d")
Jeff Brown053b8652012-06-06 16:25:03 -070057
Josh Gao344ca5a2016-08-23 11:09:06 -070058static bool signal_has_si_addr(int si_signo, int si_code) {
59 // Manually sent signals won't have si_addr.
60 if (si_code == SI_USER || si_code == SI_QUEUE || si_code == SI_TKILL) {
61 return false;
62 }
63
64 switch (si_signo) {
Christopher Ferris20303f82014-01-10 16:33:16 -080065 case SIGBUS:
Elliott Hughesa323b502014-05-16 21:12:17 -070066 case SIGFPE:
67 case SIGILL:
68 case SIGSEGV:
Dmitriy Ivanovf10aa3a2014-08-08 16:30:13 -070069 case SIGTRAP:
Christopher Ferris20303f82014-01-10 16:33:16 -080070 return true;
71 default:
72 return false;
73 }
74}
75
76static const char* get_signame(int sig) {
77 switch(sig) {
Christopher Ferris20303f82014-01-10 16:33:16 -080078 case SIGABRT: return "SIGABRT";
79 case SIGBUS: return "SIGBUS";
80 case SIGFPE: return "SIGFPE";
Elliott Hughesa323b502014-05-16 21:12:17 -070081 case SIGILL: return "SIGILL";
Elliott Hughesa323b502014-05-16 21:12:17 -070082 case SIGSEGV: return "SIGSEGV";
Elliott Hughes855fcc32014-04-25 16:05:34 -070083#if defined(SIGSTKFLT)
Christopher Ferris20303f82014-01-10 16:33:16 -080084 case SIGSTKFLT: return "SIGSTKFLT";
85#endif
86 case SIGSTOP: return "SIGSTOP";
Elliott Hughes6fff5512016-09-02 16:15:58 -070087 case SIGSYS: return "SIGSYS";
Elliott Hughesa323b502014-05-16 21:12:17 -070088 case SIGTRAP: return "SIGTRAP";
Josh Gaocbe70cb2016-10-18 18:17:52 -070089 case DEBUGGER_SIGNAL: return "<debuggerd signal>";
Christopher Ferris20303f82014-01-10 16:33:16 -080090 default: return "?";
91 }
92}
93
94static const char* get_sigcode(int signo, int code) {
95 // Try the signal-specific codes...
96 switch (signo) {
97 case SIGILL:
98 switch (code) {
Jeff Brown053b8652012-06-06 16:25:03 -070099 case ILL_ILLOPC: return "ILL_ILLOPC";
100 case ILL_ILLOPN: return "ILL_ILLOPN";
101 case ILL_ILLADR: return "ILL_ILLADR";
102 case ILL_ILLTRP: return "ILL_ILLTRP";
103 case ILL_PRVOPC: return "ILL_PRVOPC";
104 case ILL_PRVREG: return "ILL_PRVREG";
105 case ILL_COPROC: return "ILL_COPROC";
106 case ILL_BADSTK: return "ILL_BADSTK";
Christopher Ferris20303f82014-01-10 16:33:16 -0800107 }
Elliott Hughesbd395b92014-04-24 13:53:22 -0700108 static_assert(NSIGILL == ILL_BADSTK, "missing ILL_* si_code");
Christopher Ferris20303f82014-01-10 16:33:16 -0800109 break;
Jeff Brown053b8652012-06-06 16:25:03 -0700110 case SIGBUS:
Christopher Ferris20303f82014-01-10 16:33:16 -0800111 switch (code) {
Jeff Brown053b8652012-06-06 16:25:03 -0700112 case BUS_ADRALN: return "BUS_ADRALN";
113 case BUS_ADRERR: return "BUS_ADRERR";
114 case BUS_OBJERR: return "BUS_OBJERR";
Elliott Hughesbd395b92014-04-24 13:53:22 -0700115 case BUS_MCEERR_AR: return "BUS_MCEERR_AR";
116 case BUS_MCEERR_AO: return "BUS_MCEERR_AO";
Christopher Ferris20303f82014-01-10 16:33:16 -0800117 }
Elliott Hughesbd395b92014-04-24 13:53:22 -0700118 static_assert(NSIGBUS == BUS_MCEERR_AO, "missing BUS_* si_code");
Christopher Ferris20303f82014-01-10 16:33:16 -0800119 break;
Jeff Brown053b8652012-06-06 16:25:03 -0700120 case SIGFPE:
Christopher Ferris20303f82014-01-10 16:33:16 -0800121 switch (code) {
Jeff Brown053b8652012-06-06 16:25:03 -0700122 case FPE_INTDIV: return "FPE_INTDIV";
123 case FPE_INTOVF: return "FPE_INTOVF";
124 case FPE_FLTDIV: return "FPE_FLTDIV";
125 case FPE_FLTOVF: return "FPE_FLTOVF";
126 case FPE_FLTUND: return "FPE_FLTUND";
127 case FPE_FLTRES: return "FPE_FLTRES";
128 case FPE_FLTINV: return "FPE_FLTINV";
129 case FPE_FLTSUB: return "FPE_FLTSUB";
Christopher Ferris20303f82014-01-10 16:33:16 -0800130 }
Elliott Hughesbd395b92014-04-24 13:53:22 -0700131 static_assert(NSIGFPE == FPE_FLTSUB, "missing FPE_* si_code");
Christopher Ferris20303f82014-01-10 16:33:16 -0800132 break;
Jeff Brown053b8652012-06-06 16:25:03 -0700133 case SIGSEGV:
Christopher Ferris20303f82014-01-10 16:33:16 -0800134 switch (code) {
Jeff Brown053b8652012-06-06 16:25:03 -0700135 case SEGV_MAPERR: return "SEGV_MAPERR";
136 case SEGV_ACCERR: return "SEGV_ACCERR";
Christopher Ferris5d56e282016-02-04 14:07:23 -0800137#if defined(SEGV_BNDERR)
138 case SEGV_BNDERR: return "SEGV_BNDERR";
139#endif
Christopher Ferrisf83c7922016-08-24 14:49:18 -0700140#if defined(SEGV_PKUERR)
141 case SEGV_PKUERR: return "SEGV_PKUERR";
142#endif
Christopher Ferris20303f82014-01-10 16:33:16 -0800143 }
Christopher Ferrisf83c7922016-08-24 14:49:18 -0700144#if defined(SEGV_PKUERR)
145 static_assert(NSIGSEGV == SEGV_PKUERR, "missing SEGV_* si_code");
146#elif defined(SEGV_BNDERR)
Christopher Ferris5d56e282016-02-04 14:07:23 -0800147 static_assert(NSIGSEGV == SEGV_BNDERR, "missing SEGV_* si_code");
148#else
Elliott Hughesbd395b92014-04-24 13:53:22 -0700149 static_assert(NSIGSEGV == SEGV_ACCERR, "missing SEGV_* si_code");
Christopher Ferris5d56e282016-02-04 14:07:23 -0800150#endif
Christopher Ferris20303f82014-01-10 16:33:16 -0800151 break;
Elliott Hughes6fff5512016-09-02 16:15:58 -0700152#if defined(SYS_SECCOMP) // Our glibc is too old, and we build this for the host too.
153 case SIGSYS:
154 switch (code) {
155 case SYS_SECCOMP: return "SYS_SECCOMP";
156 }
157 static_assert(NSIGSYS == SYS_SECCOMP, "missing SYS_* si_code");
158 break;
159#endif
Elliott Hughes8f7d4432012-12-10 10:29:05 -0800160 case SIGTRAP:
Christopher Ferris20303f82014-01-10 16:33:16 -0800161 switch (code) {
Elliott Hughes8f7d4432012-12-10 10:29:05 -0800162 case TRAP_BRKPT: return "TRAP_BRKPT";
163 case TRAP_TRACE: return "TRAP_TRACE";
Elliott Hughesbd395b92014-04-24 13:53:22 -0700164 case TRAP_BRANCH: return "TRAP_BRANCH";
165 case TRAP_HWBKPT: return "TRAP_HWBKPT";
Christopher Ferris20303f82014-01-10 16:33:16 -0800166 }
Elliott Hughesbd395b92014-04-24 13:53:22 -0700167 static_assert(NSIGTRAP == TRAP_HWBKPT, "missing TRAP_* si_code");
Christopher Ferris20303f82014-01-10 16:33:16 -0800168 break;
169 }
170 // Then the other codes...
171 switch (code) {
172 case SI_USER: return "SI_USER";
Christopher Ferris20303f82014-01-10 16:33:16 -0800173 case SI_KERNEL: return "SI_KERNEL";
Christopher Ferris20303f82014-01-10 16:33:16 -0800174 case SI_QUEUE: return "SI_QUEUE";
175 case SI_TIMER: return "SI_TIMER";
176 case SI_MESGQ: return "SI_MESGQ";
Elliott Hughes8f7d4432012-12-10 10:29:05 -0800177 case SI_ASYNCIO: return "SI_ASYNCIO";
Christopher Ferris20303f82014-01-10 16:33:16 -0800178 case SI_SIGIO: return "SI_SIGIO";
Christopher Ferris20303f82014-01-10 16:33:16 -0800179 case SI_TKILL: return "SI_TKILL";
Elliott Hughesbd395b92014-04-24 13:53:22 -0700180 case SI_DETHREAD: return "SI_DETHREAD";
Christopher Ferris20303f82014-01-10 16:33:16 -0800181 }
182 // Then give up...
183 return "?";
Jeff Brown053b8652012-06-06 16:25:03 -0700184}
185
Brigid Smith9c8dacc2014-06-02 15:02:20 -0700186static void dump_header_info(log_t* log) {
187 char fingerprint[PROPERTY_VALUE_MAX];
Christopher Ferris20303f82014-01-10 16:33:16 -0800188 char revision[PROPERTY_VALUE_MAX];
Ben Chengd7760c12012-09-19 16:04:01 -0700189
Brigid Smith9c8dacc2014-06-02 15:02:20 -0700190 property_get("ro.build.fingerprint", fingerprint, "unknown");
Christopher Ferris20303f82014-01-10 16:33:16 -0800191 property_get("ro.revision", revision, "unknown");
Ben Chengd7760c12012-09-19 16:04:01 -0700192
Brigid Smith62ba4892014-06-10 11:53:08 -0700193 _LOG(log, logtype::HEADER, "Build fingerprint: '%s'\n", fingerprint);
194 _LOG(log, logtype::HEADER, "Revision: '%s'\n", revision);
195 _LOG(log, logtype::HEADER, "ABI: '%s'\n", ABI_STRING);
Jeff Brown053b8652012-06-06 16:25:03 -0700196}
197
Josh Gaoa04c8022016-08-11 12:50:32 -0700198static void dump_signal_info(log_t* log, pid_t tid) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800199 siginfo_t si;
Christopher Ferris20303f82014-01-10 16:33:16 -0800200 memset(&si, 0, sizeof(si));
Elliott Hughes855fcc32014-04-25 16:05:34 -0700201 if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si) == -1) {
Christopher Ferrisb36b5922015-06-17 18:35:59 -0700202 ALOGE("cannot get siginfo: %s\n", strerror(errno));
Elliott Hughes855fcc32014-04-25 16:05:34 -0700203 return;
Christopher Ferris20303f82014-01-10 16:33:16 -0800204 }
Elliott Hughes855fcc32014-04-25 16:05:34 -0700205
Elliott Hughes855fcc32014-04-25 16:05:34 -0700206 char addr_desc[32]; // ", fault addr 0x1234"
Josh Gao344ca5a2016-08-23 11:09:06 -0700207 if (signal_has_si_addr(si.si_signo, si.si_code)) {
Elliott Hughes855fcc32014-04-25 16:05:34 -0700208 snprintf(addr_desc, sizeof(addr_desc), "%p", si.si_addr);
209 } else {
210 snprintf(addr_desc, sizeof(addr_desc), "--------");
211 }
212
Josh Gaoa04c8022016-08-11 12:50:32 -0700213 _LOG(log, logtype::HEADER, "signal %d (%s), code %d (%s), fault addr %s\n", si.si_signo,
214 get_signame(si.si_signo), si.si_code, get_sigcode(si.si_signo, si.si_code), addr_desc);
Jeff Brown053b8652012-06-06 16:25:03 -0700215}
216
Brigid Smith62ba4892014-06-10 11:53:08 -0700217static void dump_thread_info(log_t* log, pid_t pid, pid_t tid) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800218 char path[64];
219 char threadnamebuf[1024];
Christopher Ferris157f2722016-05-05 11:21:11 -0700220 char* threadname = nullptr;
Christopher Ferris20303f82014-01-10 16:33:16 -0800221 FILE *fp;
Jeff Brown053b8652012-06-06 16:25:03 -0700222
Christopher Ferris20303f82014-01-10 16:33:16 -0800223 snprintf(path, sizeof(path), "/proc/%d/comm", tid);
224 if ((fp = fopen(path, "r"))) {
225 threadname = fgets(threadnamebuf, sizeof(threadnamebuf), fp);
226 fclose(fp);
227 if (threadname) {
228 size_t len = strlen(threadname);
229 if (len && threadname[len - 1] == '\n') {
230 threadname[len - 1] = '\0';
231 }
232 }
233 }
Mark Salyzyn45ae4462014-07-25 12:25:48 -0700234 // Blacklist logd, logd.reader, logd.writer, logd.auditd, logd.control ...
235 static const char logd[] = "logd";
Christopher Ferris157f2722016-05-05 11:21:11 -0700236 if (threadname != nullptr && !strncmp(threadname, logd, sizeof(logd) - 1)
Mark Salyzyn45ae4462014-07-25 12:25:48 -0700237 && (!threadname[sizeof(logd) - 1] || (threadname[sizeof(logd) - 1] == '.'))) {
238 log->should_retrieve_logcat = false;
239 }
Christopher Ferris20303f82014-01-10 16:33:16 -0800240
Brigid Smith62ba4892014-06-10 11:53:08 -0700241 char procnamebuf[1024];
Christopher Ferris157f2722016-05-05 11:21:11 -0700242 char* procname = nullptr;
Christopher Ferris20303f82014-01-10 16:33:16 -0800243
Brigid Smith62ba4892014-06-10 11:53:08 -0700244 snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
245 if ((fp = fopen(path, "r"))) {
246 procname = fgets(procnamebuf, sizeof(procnamebuf), fp);
247 fclose(fp);
Christopher Ferris20303f82014-01-10 16:33:16 -0800248 }
Brigid Smith62ba4892014-06-10 11:53:08 -0700249
Brigid Smithf4732002014-06-23 11:03:40 -0700250 _LOG(log, logtype::HEADER, "pid: %d, tid: %d, name: %s >>> %s <<<\n", pid, tid,
Brigid Smith62ba4892014-06-10 11:53:08 -0700251 threadname ? threadname : "UNKNOWN", procname ? procname : "UNKNOWN");
Christopher Ferris20303f82014-01-10 16:33:16 -0800252}
Jeff Brown053b8652012-06-06 16:25:03 -0700253
Christopher Ferris20303f82014-01-10 16:33:16 -0800254static void dump_stack_segment(
Brigid Smith62ba4892014-06-10 11:53:08 -0700255 Backtrace* backtrace, log_t* log, uintptr_t* sp, size_t words, int label) {
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800256 // Read the data all at once.
257 word_t stack_data[words];
258 size_t bytes_read = backtrace->Read(*sp, reinterpret_cast<uint8_t*>(&stack_data[0]), sizeof(word_t) * words);
259 words = bytes_read / sizeof(word_t);
260 std::string line;
Christopher Ferris20303f82014-01-10 16:33:16 -0800261 for (size_t i = 0; i < words; i++) {
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800262 line = " ";
263 if (i == 0 && label >= 0) {
264 // Print the label once.
265 line += android::base::StringPrintf("#%02d ", label);
266 } else {
267 line += " ";
Christopher Ferris20303f82014-01-10 16:33:16 -0800268 }
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800269 line += android::base::StringPrintf("%" PRIPTR " %" PRIPTR, *sp, stack_data[i]);
Christopher Ferris20303f82014-01-10 16:33:16 -0800270
Christopher Ferris12385e32015-02-06 13:22:01 -0800271 backtrace_map_t map;
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800272 backtrace->FillInMap(stack_data[i], &map);
273 if (BacktraceMap::IsValid(map) && !map.name.empty()) {
274 line += " " + map.name;
275 uintptr_t offset = 0;
276 std::string func_name(backtrace->GetFunctionName(stack_data[i], &offset));
277 if (!func_name.empty()) {
278 line += " (" + func_name;
Christopher Ferris20303f82014-01-10 16:33:16 -0800279 if (offset) {
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800280 line += android::base::StringPrintf("+%" PRIuPTR, offset);
Jeff Brown053b8652012-06-06 16:25:03 -0700281 }
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800282 line += ')';
Christopher Ferris20303f82014-01-10 16:33:16 -0800283 }
Jeff Brown053b8652012-06-06 16:25:03 -0700284 }
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800285 _LOG(log, logtype::STACK, "%s\n", line.c_str());
Christopher Ferris20303f82014-01-10 16:33:16 -0800286
Pavel Chupinc6c194c2013-11-21 23:17:20 +0400287 *sp += sizeof(word_t);
Christopher Ferris20303f82014-01-10 16:33:16 -0800288 }
Jeff Brown053b8652012-06-06 16:25:03 -0700289}
290
Brigid Smith62ba4892014-06-10 11:53:08 -0700291static void dump_stack(Backtrace* backtrace, log_t* log) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800292 size_t first = 0, last;
293 for (size_t i = 0; i < backtrace->NumFrames(); i++) {
294 const backtrace_frame_data_t* frame = backtrace->GetFrame(i);
295 if (frame->sp) {
296 if (!first) {
297 first = i+1;
298 }
299 last = i;
Jeff Brown053b8652012-06-06 16:25:03 -0700300 }
Christopher Ferris20303f82014-01-10 16:33:16 -0800301 }
302 if (!first) {
303 return;
304 }
305 first--;
306
Christopher Ferris20303f82014-01-10 16:33:16 -0800307 // Dump a few words before the first frame.
Pavel Chupinc6c194c2013-11-21 23:17:20 +0400308 word_t sp = backtrace->GetFrame(first)->sp - STACK_WORDS * sizeof(word_t);
Brigid Smith62ba4892014-06-10 11:53:08 -0700309 dump_stack_segment(backtrace, log, &sp, STACK_WORDS, -1);
Christopher Ferris20303f82014-01-10 16:33:16 -0800310
311 // Dump a few words from all successive frames.
312 // Only log the first 3 frames, put the rest in the tombstone.
313 for (size_t i = first; i <= last; i++) {
314 const backtrace_frame_data_t* frame = backtrace->GetFrame(i);
315 if (sp != frame->sp) {
Brigid Smith62ba4892014-06-10 11:53:08 -0700316 _LOG(log, logtype::STACK, " ........ ........\n");
Christopher Ferris20303f82014-01-10 16:33:16 -0800317 sp = frame->sp;
318 }
Christopher Ferris20303f82014-01-10 16:33:16 -0800319 if (i == last) {
Brigid Smith62ba4892014-06-10 11:53:08 -0700320 dump_stack_segment(backtrace, log, &sp, STACK_WORDS, i);
Christopher Ferris20303f82014-01-10 16:33:16 -0800321 if (sp < frame->sp + frame->stack_size) {
Brigid Smith62ba4892014-06-10 11:53:08 -0700322 _LOG(log, logtype::STACK, " ........ ........\n");
Christopher Ferris20303f82014-01-10 16:33:16 -0800323 }
324 } else {
Pavel Chupinc6c194c2013-11-21 23:17:20 +0400325 size_t words = frame->stack_size / sizeof(word_t);
Christopher Ferris20303f82014-01-10 16:33:16 -0800326 if (words == 0) {
327 words = 1;
328 } else if (words > STACK_WORDS) {
329 words = STACK_WORDS;
330 }
Brigid Smith62ba4892014-06-10 11:53:08 -0700331 dump_stack_segment(backtrace, log, &sp, words, i);
Christopher Ferris20303f82014-01-10 16:33:16 -0800332 }
333 }
Jeff Brown053b8652012-06-06 16:25:03 -0700334}
335
Christopher Ferris862fe022015-06-02 14:52:44 -0700336static std::string get_addr_string(uintptr_t addr) {
337 std::string addr_str;
338#if defined(__LP64__)
339 addr_str = android::base::StringPrintf("%08x'%08x",
340 static_cast<uint32_t>(addr >> 32),
341 static_cast<uint32_t>(addr & 0xffffffff));
342#else
343 addr_str = android::base::StringPrintf("%08x", addr);
344#endif
345 return addr_str;
346}
347
Josh Gao7c89f9e2016-01-13 17:57:14 -0800348static void dump_abort_message(Backtrace* backtrace, log_t* log, uintptr_t address) {
349 if (address == 0) {
350 return;
351 }
352
353 address += sizeof(size_t); // Skip the buffer length.
354
355 char msg[512];
356 memset(msg, 0, sizeof(msg));
357 char* p = &msg[0];
358 while (p < &msg[sizeof(msg)]) {
359 word_t data;
360 size_t len = sizeof(word_t);
361 if (!backtrace->ReadWord(address, &data)) {
362 break;
363 }
364 address += sizeof(word_t);
365
366 while (len > 0 && (*p++ = (data >> (sizeof(word_t) - len) * 8) & 0xff) != 0) {
367 len--;
368 }
369 }
370 msg[sizeof(msg) - 1] = '\0';
371
372 _LOG(log, logtype::HEADER, "Abort message: '%s'\n", msg);
373}
374
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800375static void dump_all_maps(Backtrace* backtrace, BacktraceMap* map, log_t* log, pid_t tid) {
376 bool print_fault_address_marker = false;
Christopher Ferrisab9e7dc2015-02-09 17:06:27 -0800377 uintptr_t addr = 0;
Christopher Ferris20303f82014-01-10 16:33:16 -0800378 siginfo_t si;
379 memset(&si, 0, sizeof(si));
Christopher Ferris862fe022015-06-02 14:52:44 -0700380 if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si) != -1) {
Josh Gao344ca5a2016-08-23 11:09:06 -0700381 print_fault_address_marker = signal_has_si_addr(si.si_signo, si.si_code);
Christopher Ferrisab9e7dc2015-02-09 17:06:27 -0800382 addr = reinterpret_cast<uintptr_t>(si.si_addr);
Christopher Ferris862fe022015-06-02 14:52:44 -0700383 } else {
Christopher Ferrisb36b5922015-06-17 18:35:59 -0700384 ALOGE("Cannot get siginfo for %d: %s\n", tid, strerror(errno));
Christopher Ferris20303f82014-01-10 16:33:16 -0800385 }
Christopher Ferris20303f82014-01-10 16:33:16 -0800386
Christopher Ferris3a140042016-06-15 15:49:50 -0700387 ScopedBacktraceMapIteratorLock lock(map);
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800388 _LOG(log, logtype::MAPS, "\n");
389 if (!print_fault_address_marker) {
390 _LOG(log, logtype::MAPS, "memory map:\n");
391 } else {
392 _LOG(log, logtype::MAPS, "memory map: (fault address prefixed with --->)\n");
393 if (map->begin() != map->end() && addr < map->begin()->start) {
Christopher Ferris862fe022015-06-02 14:52:44 -0700394 _LOG(log, logtype::MAPS, "--->Fault address falls at %s before any mapped regions\n",
395 get_addr_string(addr).c_str());
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800396 print_fault_address_marker = false;
Brigid Smith8606eaa2014-07-07 12:33:50 -0700397 }
Brigid Smith8606eaa2014-07-07 12:33:50 -0700398 }
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800399
400 std::string line;
401 for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) {
402 line = " ";
403 if (print_fault_address_marker) {
404 if (addr < it->start) {
Christopher Ferris862fe022015-06-02 14:52:44 -0700405 _LOG(log, logtype::MAPS, "--->Fault address falls at %s between mapped regions\n",
406 get_addr_string(addr).c_str());
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800407 print_fault_address_marker = false;
408 } else if (addr >= it->start && addr < it->end) {
409 line = "--->";
410 print_fault_address_marker = false;
411 }
412 }
Christopher Ferris862fe022015-06-02 14:52:44 -0700413 line += get_addr_string(it->start) + '-' + get_addr_string(it->end - 1) + ' ';
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800414 if (it->flags & PROT_READ) {
415 line += 'r';
416 } else {
417 line += '-';
418 }
419 if (it->flags & PROT_WRITE) {
420 line += 'w';
421 } else {
422 line += '-';
423 }
424 if (it->flags & PROT_EXEC) {
425 line += 'x';
426 } else {
427 line += '-';
428 }
Christopher Ferris5c885682015-05-06 12:50:09 -0700429 line += android::base::StringPrintf(" %8" PRIxPTR " %8" PRIxPTR,
430 it->offset, it->end - it->start);
Christopher Ferris862fe022015-06-02 14:52:44 -0700431 bool space_needed = true;
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800432 if (it->name.length() > 0) {
Christopher Ferris862fe022015-06-02 14:52:44 -0700433 space_needed = false;
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800434 line += " " + it->name;
435 std::string build_id;
436 if ((it->flags & PROT_READ) && elf_get_build_id(backtrace, it->start, &build_id)) {
437 line += " (BuildId: " + build_id + ")";
438 }
439 }
Christopher Ferris2106f4b2015-05-01 15:02:03 -0700440 if (it->load_base != 0) {
Christopher Ferris862fe022015-06-02 14:52:44 -0700441 if (space_needed) {
442 line += ' ';
443 }
Christopher Ferris2106f4b2015-05-01 15:02:03 -0700444 line += android::base::StringPrintf(" (load base 0x%" PRIxPTR ")", it->load_base);
445 }
Christopher Ferrisa21bd932015-02-27 13:39:47 -0800446 _LOG(log, logtype::MAPS, "%s\n", line.c_str());
447 }
448 if (print_fault_address_marker) {
Christopher Ferris862fe022015-06-02 14:52:44 -0700449 _LOG(log, logtype::MAPS, "--->Fault address falls at %s after any mapped regions\n",
450 get_addr_string(addr).c_str());
Christopher Ferris20303f82014-01-10 16:33:16 -0800451 }
Jeff Brown053b8652012-06-06 16:25:03 -0700452}
453
Christopher Ferrisab9e7dc2015-02-09 17:06:27 -0800454static void dump_backtrace_and_stack(Backtrace* backtrace, log_t* log) {
455 if (backtrace->NumFrames()) {
456 _LOG(log, logtype::BACKTRACE, "\nbacktrace:\n");
457 dump_backtrace_to_log(backtrace, log, " ");
Brigid Smith62ba4892014-06-10 11:53:08 -0700458
Christopher Ferrisab9e7dc2015-02-09 17:06:27 -0800459 _LOG(log, logtype::STACK, "\nstack:\n");
460 dump_stack(backtrace, log);
461 }
Jeff Brown053b8652012-06-06 16:25:03 -0700462}
463
Josh Gaoa04c8022016-08-11 12:50:32 -0700464static void dump_thread(log_t* log, pid_t pid, pid_t tid, BacktraceMap* map,
465 uintptr_t abort_msg_address, bool primary_thread) {
Josh Gao7c89f9e2016-01-13 17:57:14 -0800466 log->current_tid = tid;
467 if (!primary_thread) {
Brigid Smith62ba4892014-06-10 11:53:08 -0700468 _LOG(log, logtype::THREAD, "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n");
Josh Gao7c89f9e2016-01-13 17:57:14 -0800469 }
470 dump_thread_info(log, pid, tid);
Josh Gaoa04c8022016-08-11 12:50:32 -0700471 dump_signal_info(log, tid);
Christopher Ferris20303f82014-01-10 16:33:16 -0800472
Josh Gao7c89f9e2016-01-13 17:57:14 -0800473 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map));
474 if (primary_thread) {
475 dump_abort_message(backtrace.get(), log, abort_msg_address);
476 }
477 dump_registers(log, tid);
478 if (backtrace->Unwind(0)) {
479 dump_backtrace_and_stack(backtrace.get(), log);
480 } else {
481 ALOGE("Unwind failed: pid = %d, tid = %d", pid, tid);
482 }
Brigid Smith62ba4892014-06-10 11:53:08 -0700483
Josh Gao7c89f9e2016-01-13 17:57:14 -0800484 if (primary_thread) {
485 dump_memory_and_code(log, backtrace.get());
486 if (map) {
487 dump_all_maps(backtrace.get(), map, log, tid);
Christopher Ferris20303f82014-01-10 16:33:16 -0800488 }
489 }
490
Josh Gao7c89f9e2016-01-13 17:57:14 -0800491 log->current_tid = log->crashed_tid;
Jeff Brown053b8652012-06-06 16:25:03 -0700492}
493
Christopher Ferris20303f82014-01-10 16:33:16 -0800494// Reads the contents of the specified log device, filters out the entries
495// that don't match the specified pid, and writes them to the tombstone file.
496//
Mark Salyzyn17e85c02014-06-27 15:55:19 -0700497// If "tail" is non-zero, log the last "tail" number of lines.
Mark Salyzyn989980c2014-05-14 12:37:22 -0700498static EventTagMap* g_eventTagMap = NULL;
499
Mark Salyzyn17e85c02014-06-27 15:55:19 -0700500static void dump_log_file(
501 log_t* log, pid_t pid, const char* filename, unsigned int tail) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800502 bool first = true;
Mark Salyzyn17e85c02014-06-27 15:55:19 -0700503 struct logger_list* logger_list;
Jeff Brown053b8652012-06-06 16:25:03 -0700504
Mark Salyzyn45ae4462014-07-25 12:25:48 -0700505 if (!log->should_retrieve_logcat) {
506 return;
507 }
508
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800509 logger_list = android_logger_list_open(
Mark Salyzyn2d3f38a2015-01-26 10:46:44 -0800510 android_name_to_log_id(filename), ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, tail, pid);
Jeff Brown053b8652012-06-06 16:25:03 -0700511
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800512 if (!logger_list) {
Brigid Smith50eb5462014-06-18 14:17:57 -0700513 ALOGE("Unable to open %s: %s\n", filename, strerror(errno));
Christopher Ferris20303f82014-01-10 16:33:16 -0800514 return;
515 }
516
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800517 struct log_msg log_entry;
Christopher Ferris20303f82014-01-10 16:33:16 -0800518
519 while (true) {
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800520 ssize_t actual = android_logger_list_read(logger_list, &log_entry);
Mark Salyzyn17e85c02014-06-27 15:55:19 -0700521 struct logger_entry* entry;
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800522
Christopher Ferris20303f82014-01-10 16:33:16 -0800523 if (actual < 0) {
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800524 if (actual == -EINTR) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800525 // interrupted by signal, retry
526 continue;
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800527 } else if (actual == -EAGAIN) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800528 // non-blocking EOF; we're done
529 break;
530 } else {
Christopher Ferrisb36b5922015-06-17 18:35:59 -0700531 ALOGE("Error while reading log: %s\n", strerror(-actual));
Christopher Ferris20303f82014-01-10 16:33:16 -0800532 break;
533 }
534 } else if (actual == 0) {
Christopher Ferrisb36b5922015-06-17 18:35:59 -0700535 ALOGE("Got zero bytes while reading log: %s\n", strerror(errno));
Christopher Ferris20303f82014-01-10 16:33:16 -0800536 break;
Jeff Brown053b8652012-06-06 16:25:03 -0700537 }
538
Brigid Smith50eb5462014-06-18 14:17:57 -0700539 // NOTE: if you ALOGV something here, this will spin forever,
Christopher Ferris20303f82014-01-10 16:33:16 -0800540 // because you will be writing as fast as you're reading. Any
541 // high-frequency debug diagnostics should just be written to
542 // the tombstone file.
Jeff Brown053b8652012-06-06 16:25:03 -0700543
Mark Salyzyn17e85c02014-06-27 15:55:19 -0700544 entry = &log_entry.entry_v1;
Jeff Brown053b8652012-06-06 16:25:03 -0700545
Christopher Ferris20303f82014-01-10 16:33:16 -0800546 if (first) {
Mark Salyzyne43290d2014-06-27 10:32:22 -0700547 _LOG(log, logtype::LOGS, "--------- %slog %s\n",
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800548 tail ? "tail end of " : "", filename);
Christopher Ferris20303f82014-01-10 16:33:16 -0800549 first = false;
550 }
551
552 // Msg format is: <priority:1><tag:N>\0<message:N>\0
553 //
554 // We want to display it in the same format as "logcat -v threadtime"
555 // (although in this case the pid is redundant).
Christopher Ferris20303f82014-01-10 16:33:16 -0800556 static const char* kPrioChars = "!.VDIWEFS";
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800557 unsigned hdr_size = log_entry.entry.hdr_size;
558 if (!hdr_size) {
559 hdr_size = sizeof(log_entry.entry_v1);
560 }
Mark Salyzyn305374c2016-08-18 14:59:41 -0700561 if ((hdr_size < sizeof(log_entry.entry_v1)) ||
562 (hdr_size > sizeof(log_entry.entry))) {
563 continue;
564 }
Mark Salyzyn989980c2014-05-14 12:37:22 -0700565 char* msg = reinterpret_cast<char*>(log_entry.buf) + hdr_size;
566
567 char timeBuf[32];
568 time_t sec = static_cast<time_t>(entry->sec);
569 struct tm tmBuf;
570 struct tm* ptm;
571 ptm = localtime_r(&sec, &tmBuf);
572 strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);
573
574 if (log_entry.id() == LOG_ID_EVENTS) {
575 if (!g_eventTagMap) {
Mark Salyzyn1179eb82016-11-11 09:48:56 -0800576 g_eventTagMap = android_openEventTagMap(NULL);
Mark Salyzyn989980c2014-05-14 12:37:22 -0700577 }
578 AndroidLogEntry e;
579 char buf[512];
580 android_log_processBinaryLogBuffer(entry, &e, g_eventTagMap, buf, sizeof(buf));
Mark Salyzyn9f53cac2016-10-24 13:11:46 -0700581 _LOG(log, logtype::LOGS, "%s.%03d %5d %5d %c %-8.*s: %s\n",
Mark Salyzyn989980c2014-05-14 12:37:22 -0700582 timeBuf, entry->nsec / 1000000, entry->pid, entry->tid,
Mark Salyzyn9f53cac2016-10-24 13:11:46 -0700583 'I', (int)e.tagLen, e.tag, e.message);
Mark Salyzyn989980c2014-05-14 12:37:22 -0700584 continue;
585 }
586
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800587 unsigned char prio = msg[0];
588 char* tag = msg + 1;
589 msg = tag + strlen(tag) + 1;
Christopher Ferris20303f82014-01-10 16:33:16 -0800590
591 // consume any trailing newlines
Mark Salyzynfca0bd12013-12-12 12:21:20 -0800592 char* nl = msg + strlen(msg) - 1;
593 while (nl >= msg && *nl == '\n') {
Mark Salyzyn17e85c02014-06-27 15:55:19 -0700594 *nl-- = '\0';
Christopher Ferris20303f82014-01-10 16:33:16 -0800595 }
596
597 char prioChar = (prio < strlen(kPrioChars) ? kPrioChars[prio] : '?');
598
Mark Salyzynfca0bd12013-12-12 12:21:20 -0800599 // Look for line breaks ('\n') and display each text line
600 // on a separate line, prefixed with the header, like logcat does.
601 do {
602 nl = strchr(msg, '\n');
603 if (nl) {
604 *nl = '\0';
605 ++nl;
606 }
607
Brigid Smith62ba4892014-06-10 11:53:08 -0700608 _LOG(log, logtype::LOGS, "%s.%03d %5d %5d %c %-8s: %s\n",
Mark Salyzynfca0bd12013-12-12 12:21:20 -0800609 timeBuf, entry->nsec / 1000000, entry->pid, entry->tid,
610 prioChar, tag, msg);
Mark Salyzynfca0bd12013-12-12 12:21:20 -0800611 } while ((msg = nl));
Christopher Ferris20303f82014-01-10 16:33:16 -0800612 }
Jeff Brown053b8652012-06-06 16:25:03 -0700613
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800614 android_logger_list_free(logger_list);
Jeff Brown053b8652012-06-06 16:25:03 -0700615}
616
Christopher Ferris20303f82014-01-10 16:33:16 -0800617// Dumps the logs generated by the specified pid to the tombstone, from both
618// "system" and "main" log devices. Ideally we'd interleave the output.
Mark Salyzyn17e85c02014-06-27 15:55:19 -0700619static void dump_logs(log_t* log, pid_t pid, unsigned int tail) {
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800620 dump_log_file(log, pid, "system", tail);
621 dump_log_file(log, pid, "main", tail);
Jeff Brown053b8652012-06-06 16:25:03 -0700622}
623
Christopher Ferris20303f82014-01-10 16:33:16 -0800624// Dumps all information about the specified pid to the tombstone.
Richard Uhler53fb32f2016-10-28 16:37:33 +0100625static void dump_crash(log_t* log, BacktraceMap* map,
626 const OpenFilesList& open_files, pid_t pid, pid_t tid,
Josh Gaoa04c8022016-08-11 12:50:32 -0700627 const std::set<pid_t>& siblings, uintptr_t abort_msg_address) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800628 // don't copy log messages to tombstone unless this is a dev device
Josh Gaocbe70cb2016-10-18 18:17:52 -0700629 char value[PROPERTY_VALUE_MAX];
630 property_get("ro.debuggable", value, "0");
631 bool want_logs = (value[0] == '1');
Jeff Brown053b8652012-06-06 16:25:03 -0700632
Brigid Smith62ba4892014-06-10 11:53:08 -0700633 _LOG(log, logtype::HEADER,
Christopher Ferris20303f82014-01-10 16:33:16 -0800634 "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
Brigid Smith9c8dacc2014-06-02 15:02:20 -0700635 dump_header_info(log);
Josh Gaoa04c8022016-08-11 12:50:32 -0700636 dump_thread(log, pid, tid, map, abort_msg_address, true);
Christopher Ferris20303f82014-01-10 16:33:16 -0800637 if (want_logs) {
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800638 dump_logs(log, pid, 5);
Christopher Ferris20303f82014-01-10 16:33:16 -0800639 }
Jeff Brown053b8652012-06-06 16:25:03 -0700640
Josh Gao7c89f9e2016-01-13 17:57:14 -0800641 if (!siblings.empty()) {
642 for (pid_t sibling : siblings) {
Josh Gaoa04c8022016-08-11 12:50:32 -0700643 dump_thread(log, pid, sibling, map, 0, false);
Josh Gao7c89f9e2016-01-13 17:57:14 -0800644 }
Christopher Ferris20303f82014-01-10 16:33:16 -0800645 }
Christopher Ferris98464972014-01-06 19:16:33 -0800646
Richard Uhler53fb32f2016-10-28 16:37:33 +0100647 _LOG(log, logtype::OPEN_FILES, "\nopen files:\n");
648 dump_open_files_list_to_log(open_files, log, " ");
649
Christopher Ferris20303f82014-01-10 16:33:16 -0800650 if (want_logs) {
Mark Salyzyn22b5cef2013-11-22 10:53:34 -0800651 dump_logs(log, pid, 0);
Christopher Ferris20303f82014-01-10 16:33:16 -0800652 }
Jeff Brown053b8652012-06-06 16:25:03 -0700653}
654
Josh Gaoe7a9e522015-11-17 13:57:03 -0800655// open_tombstone - find an available tombstone slot, if any, of the
Christopher Ferris20303f82014-01-10 16:33:16 -0800656// form tombstone_XX where XX is 00 to MAX_TOMBSTONES-1, inclusive. If no
657// file is available, we reuse the least-recently-modified file.
Josh Gaoe7a9e522015-11-17 13:57:03 -0800658int open_tombstone(std::string* out_path) {
Christopher Ferris68bd59f2014-02-07 13:25:26 -0800659 // In a single pass, find an available slot and, in case none
Christopher Ferris20303f82014-01-10 16:33:16 -0800660 // exist, find and record the least-recently-modified file.
661 char path[128];
Josh Gaoe7a9e522015-11-17 13:57:03 -0800662 int fd = -1;
Christopher Ferris68bd59f2014-02-07 13:25:26 -0800663 int oldest = -1;
664 struct stat oldest_sb;
Christopher Ferris20303f82014-01-10 16:33:16 -0800665 for (int i = 0; i < MAX_TOMBSTONES; i++) {
Kévin PETIT4bb47722013-12-18 16:44:24 +0000666 snprintf(path, sizeof(path), TOMBSTONE_TEMPLATE, i);
Jeff Brown053b8652012-06-06 16:25:03 -0700667
Christopher Ferris68bd59f2014-02-07 13:25:26 -0800668 struct stat sb;
Josh Gaoe7a9e522015-11-17 13:57:03 -0800669 if (stat(path, &sb) == 0) {
Christopher Ferris68bd59f2014-02-07 13:25:26 -0800670 if (oldest < 0 || sb.st_mtime < oldest_sb.st_mtime) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800671 oldest = i;
Christopher Ferris68bd59f2014-02-07 13:25:26 -0800672 oldest_sb.st_mtime = sb.st_mtime;
Christopher Ferris20303f82014-01-10 16:33:16 -0800673 }
674 continue;
Jeff Brown053b8652012-06-06 16:25:03 -0700675 }
Josh Gaoe7a9e522015-11-17 13:57:03 -0800676 if (errno != ENOENT) continue;
Jeff Brown053b8652012-06-06 16:25:03 -0700677
Josh Gaoe7a9e522015-11-17 13:57:03 -0800678 fd = open(path, O_CREAT | O_EXCL | O_WRONLY | O_NOFOLLOW | O_CLOEXEC, 0600);
679 if (fd < 0) continue; // raced ?
Christopher Ferris20303f82014-01-10 16:33:16 -0800680
Josh Gaoe7a9e522015-11-17 13:57:03 -0800681 if (out_path) {
682 *out_path = path;
683 }
684 fchown(fd, AID_SYSTEM, AID_SYSTEM);
685 return fd;
Christopher Ferris20303f82014-01-10 16:33:16 -0800686 }
687
Christopher Ferris68bd59f2014-02-07 13:25:26 -0800688 if (oldest < 0) {
Josh Gaoe7a9e522015-11-17 13:57:03 -0800689 ALOGE("debuggerd: failed to find a valid tombstone, default to using tombstone 0.\n");
Christopher Ferris68bd59f2014-02-07 13:25:26 -0800690 oldest = 0;
691 }
692
Christopher Ferris20303f82014-01-10 16:33:16 -0800693 // we didn't find an available file, so we clobber the oldest one
Kévin PETIT4bb47722013-12-18 16:44:24 +0000694 snprintf(path, sizeof(path), TOMBSTONE_TEMPLATE, oldest);
Josh Gaoe7a9e522015-11-17 13:57:03 -0800695 fd = open(path, O_CREAT | O_TRUNC | O_WRONLY | O_NOFOLLOW | O_CLOEXEC, 0600);
696 if (fd < 0) {
697 ALOGE("debuggerd: failed to open tombstone file '%s': %s\n", path, strerror(errno));
698 return -1;
Christopher Ferris20303f82014-01-10 16:33:16 -0800699 }
Josh Gaoe7a9e522015-11-17 13:57:03 -0800700
701 if (out_path) {
702 *out_path = path;
703 }
704 fchown(fd, AID_SYSTEM, AID_SYSTEM);
705 return fd;
Jeff Brown053b8652012-06-06 16:25:03 -0700706}
707
Richard Uhler53fb32f2016-10-28 16:37:33 +0100708void engrave_tombstone(int tombstone_fd, BacktraceMap* map,
709 const OpenFilesList& open_files, pid_t pid, pid_t tid,
Josh Gaoa04c8022016-08-11 12:50:32 -0700710 const std::set<pid_t>& siblings, uintptr_t abort_msg_address,
711 std::string* amfd_data) {
Brigid Smith62ba4892014-06-10 11:53:08 -0700712 log_t log;
713 log.current_tid = tid;
714 log.crashed_tid = tid;
715
Josh Gaoe7a9e522015-11-17 13:57:03 -0800716 if (tombstone_fd < 0) {
717 ALOGE("debuggerd: skipping tombstone write, nothing to do.\n");
Josh Gaoe7a9e522015-11-17 13:57:03 -0800718 return;
Christopher Ferris20303f82014-01-10 16:33:16 -0800719 }
Jeff Brown053b8652012-06-06 16:25:03 -0700720
Josh Gaoe7a9e522015-11-17 13:57:03 -0800721 log.tfd = tombstone_fd;
Christopher Ferris99235e92016-05-03 16:32:13 -0700722 log.amfd_data = amfd_data;
Richard Uhler53fb32f2016-10-28 16:37:33 +0100723 dump_crash(&log, map, open_files, pid, tid, siblings, abort_msg_address);
Jeff Brown053b8652012-06-06 16:25:03 -0700724}