117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris/* 217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * Copyright (C) 2013 The Android Open Source Project 317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * 417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * Licensed under the Apache License, Version 2.0 (the "License"); 517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * you may not use this file except in compliance with the License. 617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * You may obtain a copy of the License at 717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * 817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * http://www.apache.org/licenses/LICENSE-2.0 917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * 1017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * Unless required by applicable law or agreed to in writing, software 1117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * distributed under the License is distributed on an "AS IS" BASIS, 1217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * See the License for the specific language governing permissions and 1417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * limitations under the License. 1517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris */ 1617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 1717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <errno.h> 1817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <stdlib.h> 1917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <string.h> 2017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <sys/ptrace.h> 2117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <sys/types.h> 22c58287d60166ebdb1bd39fa40e5524c868c73a9bChristopher Ferris#include <ucontext.h> 2317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <unistd.h> 2417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 2517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <string> 2617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 2717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <backtrace/Backtrace.h> 2846756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris#include <backtrace/BacktraceMap.h> 2917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 30df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris#include "BacktraceImpl.h" 31e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris#include "BacktraceLog.h" 3217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include "thread_utils.h" 3317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 3417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris//------------------------------------------------------------------------- 3517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris// Backtrace functions. 3617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris//------------------------------------------------------------------------- 3746756821c4fe238f12a6e5ea18c356398f8d8795Christopher FerrisBacktrace::Backtrace(BacktraceImpl* impl, pid_t pid, BacktraceMap* map) 3846756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris : pid_(pid), tid_(-1), map_(map), map_shared_(true), impl_(impl) { 3917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris impl_->SetParent(this); 409846497f7926fc3240c2893d89e60880c22d1fd6Christopher Ferris 4146756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris if (map_ == NULL) { 42df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris map_ = BacktraceMap::Create(pid); 4346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris map_shared_ = false; 449846497f7926fc3240c2893d89e60880c22d1fd6Christopher Ferris } 4517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 4617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 4717e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisBacktrace::~Backtrace() { 4817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if (impl_) { 4917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris delete impl_; 5017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris impl_ = NULL; 5117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 52df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris 53df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris if (map_ && !map_shared_) { 54df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris delete map_; 55df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris map_ = NULL; 56df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris } 5717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 5817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 59a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferrisbool Backtrace::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) { 60a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris return impl_->Unwind(num_ignore_frames, ucontext); 6117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 6217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 638ed46278bee3cfc4c216f3a1524744019b693200Christopher Ferrisextern "C" char* __cxa_demangle(const char* mangled, char* buf, size_t* len, 648ed46278bee3cfc4c216f3a1524744019b693200Christopher Ferris int* status); 6517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 6617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisstd::string Backtrace::GetFunctionName(uintptr_t pc, uintptr_t* offset) { 6717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris std::string func_name = impl_->GetFunctionNameRaw(pc, offset); 6817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if (!func_name.empty()) { 6917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#if defined(__APPLE__) 7017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Mac OS' __cxa_demangle demangles "f" as "float"; last tested on 10.7. 71f67c6410d12a1829b0c6d009c848d72cd0158ee4Christopher Ferris if (func_name[0] != '_') { 7217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return func_name; 7317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 7417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#endif 7517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris char* name = __cxa_demangle(func_name.c_str(), 0, 0, 0); 7617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if (name) { 7717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris func_name = name; 7817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris free(name); 7917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 8017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 8117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return func_name; 8217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 8317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 84c6c194ced095df5e777b8fa24527ebd29c8fef54Pavel Chupinbool Backtrace::VerifyReadWordArgs(uintptr_t ptr, word_t* out_value) { 85c6c194ced095df5e777b8fa24527ebd29c8fef54Pavel Chupin if (ptr & (sizeof(word_t)-1)) { 868ed46278bee3cfc4c216f3a1524744019b693200Christopher Ferris BACK_LOGW("invalid pointer %p", (void*)ptr); 87c6c194ced095df5e777b8fa24527ebd29c8fef54Pavel Chupin *out_value = (word_t)-1; 8817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return false; 8917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 9017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return true; 9117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 9217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 9317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisstd::string Backtrace::FormatFrameData(size_t frame_num) { 9446756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris if (frame_num >= frames_.size()) { 9546756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris return ""; 9646756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris } 9746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris return FormatFrameData(&frames_[frame_num]); 9820303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris} 9920303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris 10020303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferrisstd::string Backtrace::FormatFrameData(const backtrace_frame_data_t* frame) { 10117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris const char* map_name; 10246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris if (frame->map && !frame->map->name.empty()) { 10346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris map_name = frame->map->name.c_str(); 10417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } else { 10517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris map_name = "<unknown>"; 10617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 10746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 10817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris uintptr_t relative_pc; 10946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris if (frame->map) { 11046756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris relative_pc = frame->pc - frame->map->start; 11117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } else { 11217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris relative_pc = frame->pc; 11317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 11417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 11517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris char buf[512]; 11646756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris if (!frame->func_name.empty() && frame->func_offset) { 11717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris snprintf(buf, sizeof(buf), "#%02zu pc %0*" PRIxPTR " %s (%s+%" PRIuPTR ")", 11820303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris frame->num, (int)sizeof(uintptr_t)*2, relative_pc, map_name, 11946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris frame->func_name.c_str(), frame->func_offset); 12046756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris } else if (!frame->func_name.empty()) { 12120303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris snprintf(buf, sizeof(buf), "#%02zu pc %0*" PRIxPTR " %s (%s)", frame->num, 12246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris (int)sizeof(uintptr_t)*2, relative_pc, map_name, frame->func_name.c_str()); 12317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } else { 12420303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris snprintf(buf, sizeof(buf), "#%02zu pc %0*" PRIxPTR " %s", frame->num, 12517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris (int)sizeof(uintptr_t)*2, relative_pc, map_name); 12617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 12717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 12817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return buf; 12917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 13017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 13146756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferrisconst backtrace_map_t* Backtrace::FindMap(uintptr_t pc) { 13246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris return map_->Find(pc); 13346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris} 13446756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 13517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris//------------------------------------------------------------------------- 13617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris// BacktraceCurrent functions. 13717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris//------------------------------------------------------------------------- 1389846497f7926fc3240c2893d89e60880c22d1fd6Christopher FerrisBacktraceCurrent::BacktraceCurrent( 13946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris BacktraceImpl* impl, BacktraceMap* map) : Backtrace(impl, getpid(), map) { 14017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 14117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 14217e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisBacktraceCurrent::~BacktraceCurrent() { 14317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 14417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 145c6c194ced095df5e777b8fa24527ebd29c8fef54Pavel Chupinbool BacktraceCurrent::ReadWord(uintptr_t ptr, word_t* out_value) { 14617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if (!VerifyReadWordArgs(ptr, out_value)) { 14717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return false; 14817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 14917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 15046756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris const backtrace_map_t* map = FindMap(ptr); 15146756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris if (map && map->flags & PROT_READ) { 152c6c194ced095df5e777b8fa24527ebd29c8fef54Pavel Chupin *out_value = *reinterpret_cast<word_t*>(ptr); 15317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return true; 15417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } else { 1558ed46278bee3cfc4c216f3a1524744019b693200Christopher Ferris BACK_LOGW("pointer %p not in a readable map", reinterpret_cast<void*>(ptr)); 156c6c194ced095df5e777b8fa24527ebd29c8fef54Pavel Chupin *out_value = static_cast<word_t>(-1); 15717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return false; 15817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 15917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 16017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 16117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris//------------------------------------------------------------------------- 16217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris// BacktracePtrace functions. 16317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris//------------------------------------------------------------------------- 1649846497f7926fc3240c2893d89e60880c22d1fd6Christopher FerrisBacktracePtrace::BacktracePtrace( 16546756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris BacktraceImpl* impl, pid_t pid, pid_t tid, BacktraceMap* map) 16646756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris : Backtrace(impl, pid, map) { 16746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris tid_ = tid; 16817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 16917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 17017e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisBacktracePtrace::~BacktracePtrace() { 17117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 17217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 173c6c194ced095df5e777b8fa24527ebd29c8fef54Pavel Chupinbool BacktracePtrace::ReadWord(uintptr_t ptr, word_t* out_value) { 17417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if (!VerifyReadWordArgs(ptr, out_value)) { 17517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return false; 17617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 17717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 17817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#if defined(__APPLE__) 1798ed46278bee3cfc4c216f3a1524744019b693200Christopher Ferris BACK_LOGW("MacOS does not support reading from another pid."); 18017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return false; 18117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#else 18217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // ptrace() returns -1 and sets errno when the operation fails. 18317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // To disambiguate -1 from a valid result, we clear errno beforehand. 18417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris errno = 0; 18517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris *out_value = ptrace(PTRACE_PEEKTEXT, Tid(), reinterpret_cast<void*>(ptr), NULL); 186c6c194ced095df5e777b8fa24527ebd29c8fef54Pavel Chupin if (*out_value == static_cast<word_t>(-1) && errno) { 1878ed46278bee3cfc4c216f3a1524744019b693200Christopher Ferris BACK_LOGW("invalid pointer %p reading from tid %d, ptrace() strerror(errno)=%s", 1888ed46278bee3cfc4c216f3a1524744019b693200Christopher Ferris reinterpret_cast<void*>(ptr), Tid(), strerror(errno)); 18917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return false; 19017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 19117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return true; 19217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#endif 19317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 19417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 19546756821c4fe238f12a6e5ea18c356398f8d8795Christopher FerrisBacktrace* Backtrace::Create(pid_t pid, pid_t tid, BacktraceMap* map) { 196cbfc7302fb3b5d5c77d2aa7974b26983ce479aa0Christopher Ferris if (pid == BACKTRACE_CURRENT_PROCESS || pid == getpid()) { 197bc12d6329ef72147da93881a34aab763905b1039Christopher Ferris if (tid == BACKTRACE_CURRENT_THREAD || tid == gettid()) { 19846756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris return CreateCurrentObj(map); 19917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } else { 20046756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris return CreateThreadObj(tid, map); 20117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 202bc12d6329ef72147da93881a34aab763905b1039Christopher Ferris } else if (tid == BACKTRACE_CURRENT_THREAD) { 20346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris return CreatePtraceObj(pid, pid, map); 20417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } else { 20546756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris return CreatePtraceObj(pid, tid, map); 20617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 20717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 208