summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2015-05-14 15:39:52 -0700
committerChristopher Ferris <cferris@google.com>2015-05-15 11:32:53 -0700
commiteb19e766322fb57ccde989e0e35b0ac3e28a4ac2 (patch)
tree3ccf3f82433f790005edd036bdaa710be90d7702
parentc89a1774cb483f90f58cb8912e89e58f53dbb6a5 (diff)
downloadsystem_core-eb19e766322fb57ccde989e0e35b0ac3e28a4ac2.tar.gz
system_core-eb19e766322fb57ccde989e0e35b0ac3e28a4ac2.tar.bz2
system_core-eb19e766322fb57ccde989e0e35b0ac3e28a4ac2.zip
Prevent crashes if a map cannot be created.
Under some conditions, /proc/<pid>/maps might return nothing. If we try and unwind in this case, we'll crash. Check this case and fail the unwind. Add checks that no other functions try and use map_ without checking for nullptr. Add logging when an unwind fails so it's clear what happened. Bug: 21162746 Change-Id: I56ce51dda0cfc9db20475a441f118108196aa07c (cherry picked from commit 30c942cf1024bf791c28ab9b67a1f752de72248c)
-rw-r--r--debuggerd/backtrace.cpp6
-rw-r--r--debuggerd/tombstone.cpp8
-rw-r--r--libbacktrace/Backtrace.cpp4
-rw-r--r--libbacktrace/BacktraceCurrent.cpp5
-rw-r--r--libbacktrace/UnwindPtrace.cpp5
5 files changed, 26 insertions, 2 deletions
diff --git a/debuggerd/backtrace.cpp b/debuggerd/backtrace.cpp
index c2a1dbc1c..79ee4e5b2 100644
--- a/debuggerd/backtrace.cpp
+++ b/debuggerd/backtrace.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "DEBUG"
+
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
@@ -27,6 +29,8 @@
#include <sys/ptrace.h>
#include <backtrace/Backtrace.h>
+
+#include <log/log.h>
#include <UniquePtr.h>
#include "backtrace.h"
@@ -95,6 +99,8 @@ static void dump_thread(
UniquePtr<Backtrace> backtrace(Backtrace::Create(tid, BACKTRACE_CURRENT_THREAD));
if (backtrace->Unwind(0)) {
dump_backtrace_to_log(backtrace.get(), log, " ");
+ } else {
+ ALOGE("Unwind failed: tid = %d", tid);
}
if (!attached && ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index b7e6b1704..4c804ee82 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -448,6 +448,8 @@ static bool dump_sibling_thread_report(
UniquePtr<Backtrace> backtrace(Backtrace::Create(pid, new_tid, map));
if (backtrace->Unwind(0)) {
dump_backtrace_and_stack(backtrace.get(), log);
+ } else {
+ ALOGE("Unwind of sibling failed: pid = %d, tid = %d", pid, new_tid);
}
log->current_tid = log->crashed_tid;
@@ -650,9 +652,13 @@ static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, int si_code
dump_registers(log, tid);
if (backtrace->Unwind(0)) {
dump_backtrace_and_stack(backtrace.get(), log);
+ } else {
+ ALOGE("Unwind failed: pid = %d, tid = %d", pid, tid);
}
dump_memory_and_code(log, tid);
- dump_all_maps(backtrace.get(), map.get(), log, tid);
+ if (map.get() != nullptr) {
+ dump_all_maps(backtrace.get(), map.get(), log, tid);
+ }
if (want_logs) {
dump_logs(log, pid, 5);
diff --git a/libbacktrace/Backtrace.cpp b/libbacktrace/Backtrace.cpp
index 4e4003e60..128bb047b 100644
--- a/libbacktrace/Backtrace.cpp
+++ b/libbacktrace/Backtrace.cpp
@@ -114,7 +114,9 @@ std::string Backtrace::FormatFrameData(const backtrace_frame_data_t* frame) {
}
void Backtrace::FillInMap(uintptr_t pc, backtrace_map_t* map) {
- map_->FillIn(pc, map);
+ if (map_ != nullptr) {
+ map_->FillIn(pc, map);
+ }
}
Backtrace* Backtrace::Create(pid_t pid, pid_t tid, BacktraceMap* map) {
diff --git a/libbacktrace/BacktraceCurrent.cpp b/libbacktrace/BacktraceCurrent.cpp
index 14f04de5e..95cd4d1a6 100644
--- a/libbacktrace/BacktraceCurrent.cpp
+++ b/libbacktrace/BacktraceCurrent.cpp
@@ -65,6 +65,11 @@ size_t BacktraceCurrent::Read(uintptr_t addr, uint8_t* buffer, size_t bytes) {
}
bool BacktraceCurrent::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) {
+ if (GetMap() == nullptr) {
+ // Without a map object, we can't do anything.
+ return false;
+ }
+
if (ucontext) {
return UnwindFromContext(num_ignore_frames, ucontext);
}
diff --git a/libbacktrace/UnwindPtrace.cpp b/libbacktrace/UnwindPtrace.cpp
index a7c3de5b3..07c243054 100644
--- a/libbacktrace/UnwindPtrace.cpp
+++ b/libbacktrace/UnwindPtrace.cpp
@@ -48,6 +48,11 @@ UnwindPtrace::~UnwindPtrace() {
}
bool UnwindPtrace::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) {
+ if (GetMap() == nullptr) {
+ // Without a map object, we can't do anything.
+ return false;
+ }
+
if (ucontext) {
BACK_LOGW("Unwinding from a specified context not supported yet.");
return false;