diff options
32 files changed, 168 insertions, 201 deletions
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c index ce3fa30..cd5885e 100755 --- a/adb/usb_vendors.c +++ b/adb/usb_vendors.c @@ -80,6 +80,8 @@ #define VENDOR_ID_HARRIS 0x19A5 // Hisense's USB Vendor ID #define VENDOR_ID_HISENSE 0x109b +// HP's USB Vendor ID +#define VENDOR_ID_HP 0x03f0 // HTC's USB Vendor ID #define VENDOR_ID_HTC 0x0bb4 // Huawei's USB Vendor ID @@ -203,6 +205,7 @@ int builtInVendorIds[] = { VENDOR_ID_HAIER, VENDOR_ID_HARRIS, VENDOR_ID_HISENSE, + VENDOR_ID_HP, VENDOR_ID_HTC, VENDOR_ID_HUAWEI, VENDOR_ID_INQ_MOBILE, diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk index 2fe7c7a..422a86a 100644 --- a/debuggerd/Android.mk +++ b/debuggerd/Android.mk @@ -6,14 +6,20 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ - backtrace.c \ - debuggerd.c \ - getevent.c \ - tombstone.c \ - utility.c \ - $(TARGET_ARCH)/machine.c - -LOCAL_CFLAGS := -Wall -Wno-unused-parameter -std=gnu99 + backtrace.cpp \ + debuggerd.cpp \ + getevent.cpp \ + tombstone.cpp \ + utility.cpp \ + $(TARGET_ARCH)/machine.cpp \ + +LOCAL_CONLYFLAGS := -std=gnu99 +LOCAL_CPPFLAGS := -std=gnu++11 +LOCAL_CFLAGS := \ + -Wall \ + -Wno-array-bounds \ + -Werror \ + LOCAL_MODULE := debuggerd ifeq ($(ARCH_ARM_HAVE_VFP),true) @@ -30,6 +36,8 @@ LOCAL_SHARED_LIBRARIES := \ liblog \ libselinux \ +include external/stlport/libstlport.mk + include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) @@ -38,7 +46,7 @@ LOCAL_SRC_FILES += $(TARGET_ARCH)/crashglue.S LOCAL_MODULE := crasher LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS += -fstack-protector-all +LOCAL_CFLAGS += -fstack-protector-all -Wno-unused-parameter -Wno-free-nonheap-object #LOCAL_FORCE_STATIC_EXECUTABLE := true LOCAL_SHARED_LIBRARIES := libcutils liblog libc include $(BUILD_EXECUTABLE) diff --git a/debuggerd/arm/machine.c b/debuggerd/arm/machine.cpp index 4ab6026..4ab6026 100644 --- a/debuggerd/arm/machine.c +++ b/debuggerd/arm/machine.cpp diff --git a/debuggerd/backtrace.c b/debuggerd/backtrace.cpp index aa7a3c2..aa7a3c2 100644 --- a/debuggerd/backtrace.c +++ b/debuggerd/backtrace.cpp diff --git a/debuggerd/debuggerd.c b/debuggerd/debuggerd.cpp index 756f7bb..a9f59c8 100644 --- a/debuggerd/debuggerd.c +++ b/debuggerd/debuggerd.cpp @@ -27,7 +27,7 @@ #include <sys/ptrace.h> #include <sys/wait.h> -#include <sys/exec_elf.h> +#include <elf.h> #include <sys/stat.h> #include <sys/poll.h> @@ -123,7 +123,7 @@ static void wait_for_user_action(pid_t pid) { int _ = -dit; int ___ = 3*_; int _______ = 7*_; - const signed char codes[] = { + const int codes[] = { dit,_,dit,_,dit,___,dah,_,dah,_,dah,___,dit,_,dit,_,dit,_______ }; size_t s = 0; @@ -132,7 +132,7 @@ static void wait_for_user_action(pid_t pid) { init_debug_led(); enable_debug_led(); do { - int timeout = abs((int)(codes[s])) * ms; + int timeout = abs(codes[s]) * ms; int res = get_event(&e, timeout); if (res == 0) { if (e.type == EV_KEY diff --git a/debuggerd/getevent.c b/debuggerd/getevent.cpp index ebd070c..8d0b149 100644 --- a/debuggerd/getevent.c +++ b/debuggerd/getevent.cpp @@ -54,13 +54,13 @@ static int open_device(const char *device) idstr[0] = '\0'; } - new_ufds = realloc(ufds, sizeof(ufds[0]) * (nfds + 1)); + new_ufds = reinterpret_cast<pollfd*>(realloc(ufds, sizeof(ufds[0]) * (nfds + 1))); if(new_ufds == NULL) { fprintf(stderr, "out of memory\n"); return -1; } ufds = new_ufds; - new_device_names = realloc(device_names, sizeof(device_names[0]) * (nfds + 1)); + new_device_names = reinterpret_cast<char**>(realloc(device_names, sizeof(device_names[0]) * (nfds + 1))); if(new_device_names == NULL) { fprintf(stderr, "out of memory\n"); return -1; @@ -162,7 +162,7 @@ int init_getevent() const char *device_path = "/dev/input"; nfds = 1; - ufds = calloc(1, sizeof(ufds[0])); + ufds = reinterpret_cast<pollfd*>(calloc(1, sizeof(ufds[0]))); ufds[0].fd = inotify_init(); ufds[0].events = POLLIN; diff --git a/debuggerd/mips/machine.c b/debuggerd/mips/machine.cpp index 489f3c5..489f3c5 100644 --- a/debuggerd/mips/machine.c +++ b/debuggerd/mips/machine.cpp diff --git a/debuggerd/tombstone.c b/debuggerd/tombstone.cpp index aa63547..1b08e8e 100644 --- a/debuggerd/tombstone.c +++ b/debuggerd/tombstone.cpp @@ -415,7 +415,7 @@ static void dump_thread(const backtrace_context_t* context, log_t* log, /* Return true if some thread is not detached cleanly */ static bool dump_sibling_thread_report( - log_t* log, pid_t pid, pid_t tid, int* total_sleep_time_usec) { + log_t* log, pid_t pid, pid_t tid, int* total_sleep_time_usec, backtrace_map_info_t* map_info) { char task_path[64]; snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid); @@ -449,7 +449,7 @@ static bool dump_sibling_thread_report( _LOG(log, 0, "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n"); dump_thread_info(log, pid, new_tid, 0); backtrace_context_t new_context; - if (backtrace_create_context(&new_context, pid, new_tid, 0)) { + if (backtrace_create_context_with_map(&new_context, pid, new_tid, 0, map_info)) { dump_thread(&new_context, log, 0, total_sleep_time_usec); backtrace_destroy_context(&new_context); } @@ -676,7 +676,9 @@ static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, uintptr_t a } backtrace_context_t context; - if (backtrace_create_context(&context, pid, tid, 0)) { + /* Gather the map info once for all this process' threads. */ + backtrace_map_info_t* map_info = backtrace_create_map_info_list(pid); + if (backtrace_create_context_with_map(&context, pid, tid, 0, map_info)) { dump_abort_message(&context, log, abort_msg_address); dump_thread(&context, log, SCOPE_AT_FAULT, total_sleep_time_usec); backtrace_destroy_context(&context); @@ -688,9 +690,12 @@ static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, uintptr_t a bool detach_failed = false; if (dump_sibling_threads) { - detach_failed = dump_sibling_thread_report(log, pid, tid, total_sleep_time_usec); + detach_failed = dump_sibling_thread_report(log, pid, tid, total_sleep_time_usec, map_info); } + /* Destroy the previously created map info. */ + backtrace_destroy_map_info_list(map_info); + if (want_logs) { dump_logs(log, pid, false); } diff --git a/debuggerd/utility.c b/debuggerd/utility.cpp index 41be982..41be982 100644 --- a/debuggerd/utility.c +++ b/debuggerd/utility.cpp diff --git a/debuggerd/x86/machine.c b/debuggerd/x86/machine.cpp index db44b11..db44b11 100644 --- a/debuggerd/x86/machine.c +++ b/debuggerd/x86/machine.cpp diff --git a/include/backtrace/Backtrace.h b/include/backtrace/Backtrace.h index b15678c..bf4efd3 100644 --- a/include/backtrace/Backtrace.h +++ b/include/backtrace/Backtrace.h @@ -33,7 +33,9 @@ public: // If pid >= 0 and tid < 0, then the Backtrace object corresponds to a // different process. // Tracing a thread in a different process is not supported. - static Backtrace* Create(pid_t pid, pid_t tid); + // If map_info is NULL, then create the map and manage it internally. + // If map_info is not NULL, the map is still owned by the caller. + static Backtrace* Create(pid_t pid, pid_t tid, backtrace_map_info_t* map_info = NULL); virtual ~Backtrace(); @@ -70,7 +72,7 @@ public: } protected: - Backtrace(BacktraceImpl* impl); + Backtrace(BacktraceImpl* impl, pid_t pid, backtrace_map_info_t* map_info); virtual bool VerifyReadWordArgs(uintptr_t ptr, uint32_t* out_value); @@ -78,6 +80,8 @@ protected: backtrace_map_info_t* map_info_; + bool map_info_requires_delete_; + backtrace_t backtrace_; friend class BacktraceImpl; diff --git a/include/backtrace/backtrace.h b/include/backtrace/backtrace.h index 8a45690..fa81f21 100644 --- a/include/backtrace/backtrace.h +++ b/include/backtrace/backtrace.h @@ -28,8 +28,8 @@ __BEGIN_DECLS // thread from the current process will be traced. #define BACKTRACE_CURRENT_PROCESS -1 // When the tid to be traced is set to this value, then trace the specified -// pid. -#define BACKTRACE_NO_TID -1 +// current thread of the specified pid. +#define BACKTRACE_CURRENT_THREAD -1 #define MAX_BACKTRACE_FRAMES 64 @@ -73,6 +73,14 @@ typedef struct { bool backtrace_create_context( backtrace_context_t* context, pid_t pid, pid_t tid, size_t num_ignore_frames); +/* The same as backtrace_create_context, except that it is assumed that + * the pid map has already been acquired and the caller will handle freeing + * the map data. + */ +bool backtrace_create_context_with_map( + backtrace_context_t* context, pid_t pid, pid_t tid, size_t num_ignore_frames, + backtrace_map_info_t* map_info); + /* Gather the backtrace data for a pthread instead of a process. */ bool backtrace_create_thread_context( backtrace_context_t* context, pid_t tid, size_t num_ignore_frames); diff --git a/include/utils/CallStack.h b/include/utils/CallStack.h index 2056751..bfe2ddb 100644 --- a/include/utils/CallStack.h +++ b/include/utils/CallStack.h @@ -18,8 +18,9 @@ #define ANDROID_CALLSTACK_H #include <android/log.h> +#include <backtrace/backtrace.h> #include <utils/String8.h> -#include <corkscrew/backtrace.h> +#include <utils/Vector.h> #include <stdint.h> #include <sys/types.h> @@ -31,42 +32,19 @@ class Printer; // Collect/print the call stack (function, file, line) traces for a single thread. class CallStack { public: - enum { - // Prune the lowest-most stack frames until we have at most MAX_DEPTH. - MAX_DEPTH = 31, - // Placeholder for specifying the current thread when updating the stack. - CURRENT_THREAD = -1, - }; - // Create an empty call stack. No-op. CallStack(); // Create a callstack with the current thread's stack trace. // Immediately dump it to logcat using the given logtag. - CallStack(const char* logtag, int32_t ignoreDepth=1, - int32_t maxDepth=MAX_DEPTH); - // Copy the existing callstack (no other side effects). - CallStack(const CallStack& rhs); + CallStack(const char* logtag, int32_t ignoreDepth=1); ~CallStack(); - // Copy the existing callstack (no other side effects). - CallStack& operator = (const CallStack& rhs); - - // Compare call stacks by their backtrace frame memory. - bool operator == (const CallStack& rhs) const; - bool operator != (const CallStack& rhs) const; - bool operator < (const CallStack& rhs) const; - bool operator >= (const CallStack& rhs) const; - bool operator > (const CallStack& rhs) const; - bool operator <= (const CallStack& rhs) const; - - // Get the PC address for the stack frame specified by index. - const void* operator [] (int index) const; - // Reset the stack frames (same as creating an empty call stack). - void clear(); + void clear() { mFrameLines.clear(); } // Immediately collect the stack traces for the specified thread. - void update(int32_t ignoreDepth=1, int32_t maxDepth=MAX_DEPTH, pid_t tid=CURRENT_THREAD); + // The default is to dump the stack of the current call. + void update(int32_t ignoreDepth=1, pid_t tid=BACKTRACE_CURRENT_THREAD); // Dump a stack trace to the log using the supplied logtag. void log(const char* logtag, @@ -83,11 +61,10 @@ public: void print(Printer& printer) const; // Get the count of stack frames that are in this call stack. - size_t size() const { return mCount; } + size_t size() const { return mFrameLines.size(); } private: - size_t mCount; - backtrace_frame_t mStack[MAX_DEPTH]; + Vector<String8> mFrameLines; }; }; // namespace android diff --git a/include/utils/ProcessCallStack.h b/include/utils/ProcessCallStack.h index 4a86869..32458b8 100644 --- a/include/utils/ProcessCallStack.h +++ b/include/utils/ProcessCallStack.h @@ -39,7 +39,7 @@ public: ~ProcessCallStack(); // Immediately collect the stack traces for all threads. - void update(int32_t maxDepth = CallStack::MAX_DEPTH); + void update(); // Print all stack traces to the log using the supplied logtag. void log(const char* logtag, android_LogPriority priority = ANDROID_LOG_DEBUG, diff --git a/libbacktrace/Backtrace.cpp b/libbacktrace/Backtrace.cpp index b22d301..a7568e0 100644 --- a/libbacktrace/Backtrace.cpp +++ b/libbacktrace/Backtrace.cpp @@ -42,11 +42,18 @@ backtrace_t* BacktraceImpl::GetBacktraceData() { //------------------------------------------------------------------------- // Backtrace functions. //------------------------------------------------------------------------- -Backtrace::Backtrace(BacktraceImpl* impl) : impl_(impl), map_info_(NULL) { +Backtrace::Backtrace(BacktraceImpl* impl, pid_t pid, backtrace_map_info_t* map_info) + : impl_(impl), map_info_(map_info), map_info_requires_delete_(false) { impl_->SetParent(this); backtrace_.num_frames = 0; - backtrace_.pid = -1; + backtrace_.pid = pid; backtrace_.tid = -1; + + if (map_info_ == NULL) { + // Create the map and manage it internally. + map_info_ = backtrace_create_map_info_list(pid); + map_info_requires_delete_ = true; + } } Backtrace::~Backtrace() { @@ -57,7 +64,7 @@ Backtrace::~Backtrace() { } } - if (map_info_) { + if (map_info_ && map_info_requires_delete_) { backtrace_destroy_map_info_list(map_info_); map_info_ = NULL; } @@ -151,8 +158,8 @@ std::string Backtrace::FormatFrameData(size_t frame_num) { //------------------------------------------------------------------------- // BacktraceCurrent functions. //------------------------------------------------------------------------- -BacktraceCurrent::BacktraceCurrent(BacktraceImpl* impl) : Backtrace(impl) { - map_info_ = backtrace_create_map_info_list(-1); +BacktraceCurrent::BacktraceCurrent( + BacktraceImpl* impl, backtrace_map_info_t *map_info) : Backtrace(impl, getpid(), map_info) { backtrace_.pid = getpid(); } @@ -179,11 +186,9 @@ bool BacktraceCurrent::ReadWord(uintptr_t ptr, uint32_t* out_value) { //------------------------------------------------------------------------- // BacktracePtrace functions. //------------------------------------------------------------------------- -BacktracePtrace::BacktracePtrace(BacktraceImpl* impl, pid_t pid, pid_t tid) - : Backtrace(impl) { - map_info_ = backtrace_create_map_info_list(tid); - - backtrace_.pid = pid; +BacktracePtrace::BacktracePtrace( + BacktraceImpl* impl, pid_t pid, pid_t tid, backtrace_map_info_t* map_info) + : Backtrace(impl, pid, map_info) { backtrace_.tid = tid; } @@ -212,26 +217,27 @@ bool BacktracePtrace::ReadWord(uintptr_t ptr, uint32_t* out_value) { #endif } -Backtrace* Backtrace::Create(pid_t pid, pid_t tid) { +Backtrace* Backtrace::Create(pid_t pid, pid_t tid, backtrace_map_info_t* map_info) { if (pid == BACKTRACE_CURRENT_PROCESS || pid == getpid()) { - if (tid == BACKTRACE_NO_TID || tid == gettid()) { - return CreateCurrentObj(); + if (tid == BACKTRACE_CURRENT_THREAD || tid == gettid()) { + return CreateCurrentObj(map_info); } else { - return CreateThreadObj(tid); + return CreateThreadObj(tid, map_info); } - } else if (tid == BACKTRACE_NO_TID) { - return CreatePtraceObj(pid, pid); + } else if (tid == BACKTRACE_CURRENT_THREAD) { + return CreatePtraceObj(pid, pid, map_info); } else { - return CreatePtraceObj(pid, tid); + return CreatePtraceObj(pid, tid, map_info); } } //------------------------------------------------------------------------- // Common interface functions. //------------------------------------------------------------------------- -bool backtrace_create_context( - backtrace_context_t* context, pid_t pid, pid_t tid, size_t num_ignore_frames) { - Backtrace* backtrace = Backtrace::Create(pid, tid); +bool backtrace_create_context_with_map( + backtrace_context_t* context, pid_t pid, pid_t tid, size_t num_ignore_frames, + backtrace_map_info_t* map_info) { + Backtrace* backtrace = Backtrace::Create(pid, tid, map_info); if (!backtrace) { return false; } @@ -245,6 +251,12 @@ bool backtrace_create_context( return true; } +bool backtrace_create_context( + backtrace_context_t* context, pid_t pid, pid_t tid, size_t num_ignore_frames) { + return backtrace_create_context_with_map(context, pid, tid, num_ignore_frames, NULL); +} + + void backtrace_destroy_context(backtrace_context_t* context) { if (context->data) { Backtrace* backtrace = reinterpret_cast<Backtrace*>(context->data); diff --git a/libbacktrace/Backtrace.h b/libbacktrace/Backtrace.h index 00f0a10..d741ef1 100644 --- a/libbacktrace/Backtrace.h +++ b/libbacktrace/Backtrace.h @@ -45,7 +45,7 @@ protected: class BacktraceCurrent : public Backtrace { public: - BacktraceCurrent(BacktraceImpl* impl); + BacktraceCurrent(BacktraceImpl* impl, backtrace_map_info_t* map_info); virtual ~BacktraceCurrent(); bool ReadWord(uintptr_t ptr, uint32_t* out_value); @@ -53,14 +53,14 @@ public: class BacktracePtrace : public Backtrace { public: - BacktracePtrace(BacktraceImpl* impl, pid_t pid, pid_t tid); + BacktracePtrace(BacktraceImpl* impl, pid_t pid, pid_t tid, backtrace_map_info_t* map_info); virtual ~BacktracePtrace(); bool ReadWord(uintptr_t ptr, uint32_t* out_value); }; -Backtrace* CreateCurrentObj(); -Backtrace* CreatePtraceObj(pid_t pid, pid_t tid); -Backtrace* CreateThreadObj(pid_t tid); +Backtrace* CreateCurrentObj(backtrace_map_info_t* map_info); +Backtrace* CreatePtraceObj(pid_t pid, pid_t tid, backtrace_map_info_t* map_info); +Backtrace* CreateThreadObj(pid_t tid, backtrace_map_info_t* map_info); #endif // _LIBBACKTRACE_BACKTRACE_H diff --git a/libbacktrace/BacktraceThread.cpp b/libbacktrace/BacktraceThread.cpp index 8e664c4..70616b0 100644 --- a/libbacktrace/BacktraceThread.cpp +++ b/libbacktrace/BacktraceThread.cpp @@ -114,8 +114,9 @@ static void SignalHandler(int n __attribute__((unused)), siginfo_t* siginfo, } BacktraceThread::BacktraceThread( - BacktraceImpl* impl, BacktraceThreadInterface* thread_intf, pid_t tid) - : BacktraceCurrent(impl), thread_intf_(thread_intf) { + BacktraceImpl* impl, BacktraceThreadInterface* thread_intf, pid_t tid, + backtrace_map_info_t* map_info) + : BacktraceCurrent(impl, map_info), thread_intf_(thread_intf) { backtrace_.tid = tid; } diff --git a/libbacktrace/BacktraceThread.h b/libbacktrace/BacktraceThread.h index 8ed1122..bcb56c9 100644 --- a/libbacktrace/BacktraceThread.h +++ b/libbacktrace/BacktraceThread.h @@ -71,7 +71,8 @@ public: // the compiler to catch if an implementation does not properly // subclass both. BacktraceThread( - BacktraceImpl* impl, BacktraceThreadInterface* thread_intf, pid_t tid); + BacktraceImpl* impl, BacktraceThreadInterface* thread_intf, pid_t tid, + backtrace_map_info_t* map_info); virtual ~BacktraceThread(); virtual bool Unwind(size_t num_ignore_frames); diff --git a/libbacktrace/Corkscrew.cpp b/libbacktrace/Corkscrew.cpp index 2be5930..eae13c6 100644 --- a/libbacktrace/Corkscrew.cpp +++ b/libbacktrace/Corkscrew.cpp @@ -204,15 +204,15 @@ std::string CorkscrewPtrace::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) //------------------------------------------------------------------------- // C++ object creation functions. //------------------------------------------------------------------------- -Backtrace* CreateCurrentObj() { - return new BacktraceCurrent(new CorkscrewCurrent()); +Backtrace* CreateCurrentObj(backtrace_map_info_t* map_info) { + return new BacktraceCurrent(new CorkscrewCurrent(), map_info); } -Backtrace* CreatePtraceObj(pid_t pid, pid_t tid) { - return new BacktracePtrace(new CorkscrewPtrace(), pid, tid); +Backtrace* CreatePtraceObj(pid_t pid, pid_t tid, backtrace_map_info_t* map_info) { + return new BacktracePtrace(new CorkscrewPtrace(), pid, tid, map_info); } -Backtrace* CreateThreadObj(pid_t tid) { +Backtrace* CreateThreadObj(pid_t tid, backtrace_map_info_t* map_info) { CorkscrewThread* thread_obj = new CorkscrewThread(); - return new BacktraceThread(thread_obj, thread_obj, tid); + return new BacktraceThread(thread_obj, thread_obj, tid, map_info); } diff --git a/libbacktrace/UnwindCurrent.cpp b/libbacktrace/UnwindCurrent.cpp index 6c0cad6..94a82fe 100644 --- a/libbacktrace/UnwindCurrent.cpp +++ b/libbacktrace/UnwindCurrent.cpp @@ -194,11 +194,11 @@ void UnwindThread::ThreadUnwind( //------------------------------------------------------------------------- // C++ object creation function. //------------------------------------------------------------------------- -Backtrace* CreateCurrentObj() { - return new BacktraceCurrent(new UnwindCurrent()); +Backtrace* CreateCurrentObj(backtrace_map_info_t* map_info) { + return new BacktraceCurrent(new UnwindCurrent(), map_info); } -Backtrace* CreateThreadObj(pid_t tid) { +Backtrace* CreateThreadObj(pid_t tid, backtrace_map_info_t* map_info) { UnwindThread* thread_obj = new UnwindThread(); - return new BacktraceThread(thread_obj, thread_obj, tid); + return new BacktraceThread(thread_obj, thread_obj, tid, map_info); } diff --git a/libbacktrace/UnwindPtrace.cpp b/libbacktrace/UnwindPtrace.cpp index a734a24..7a9bbdd 100644 --- a/libbacktrace/UnwindPtrace.cpp +++ b/libbacktrace/UnwindPtrace.cpp @@ -131,6 +131,6 @@ std::string UnwindPtrace::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) { //------------------------------------------------------------------------- // C++ object creation function. //------------------------------------------------------------------------- -Backtrace* CreatePtraceObj(pid_t pid, pid_t tid) { - return new BacktracePtrace(new UnwindPtrace(), pid, tid); +Backtrace* CreatePtraceObj(pid_t pid, pid_t tid, backtrace_map_info_t* map_info) { + return new BacktracePtrace(new UnwindPtrace(), pid, tid, map_info); } diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp index 2603e1f..b894446 100644 --- a/libbacktrace/backtrace_test.cpp +++ b/libbacktrace/backtrace_test.cpp @@ -143,7 +143,8 @@ void VerifyLevelDump(const backtrace_t* backtrace) { void VerifyLevelBacktrace(void*) { backtrace_context_t context; - ASSERT_TRUE(backtrace_create_context(&context, BACKTRACE_CURRENT_PROCESS, BACKTRACE_NO_TID, 0)); + ASSERT_TRUE(backtrace_create_context(&context, BACKTRACE_CURRENT_PROCESS, + BACKTRACE_CURRENT_THREAD, 0)); VerifyLevelDump(context.backtrace); @@ -165,7 +166,8 @@ void VerifyMaxDump(const backtrace_t* backtrace) { void VerifyMaxBacktrace(void*) { backtrace_context_t context; - ASSERT_TRUE(backtrace_create_context(&context, BACKTRACE_CURRENT_PROCESS, BACKTRACE_NO_TID, 0)); + ASSERT_TRUE(backtrace_create_context(&context, BACKTRACE_CURRENT_PROCESS, + BACKTRACE_CURRENT_THREAD, 0)); VerifyMaxDump(context.backtrace); @@ -232,15 +234,18 @@ void VerifyIgnoreFrames( void VerifyLevelIgnoreFrames(void*) { backtrace_context_t all; - ASSERT_TRUE(backtrace_create_context(&all, BACKTRACE_CURRENT_PROCESS, BACKTRACE_NO_TID, 0)); + ASSERT_TRUE(backtrace_create_context(&all, BACKTRACE_CURRENT_PROCESS, + BACKTRACE_CURRENT_THREAD, 0)); ASSERT_TRUE(all.backtrace != NULL); backtrace_context_t ign1; - ASSERT_TRUE(backtrace_create_context(&ign1, BACKTRACE_CURRENT_PROCESS, BACKTRACE_NO_TID, 1)); + ASSERT_TRUE(backtrace_create_context(&ign1, BACKTRACE_CURRENT_PROCESS, + BACKTRACE_CURRENT_THREAD, 1)); ASSERT_TRUE(ign1.backtrace != NULL); backtrace_context_t ign2; - ASSERT_TRUE(backtrace_create_context(&ign2, BACKTRACE_CURRENT_PROCESS, BACKTRACE_NO_TID, 2)); + ASSERT_TRUE(backtrace_create_context(&ign2, BACKTRACE_CURRENT_PROCESS, + BACKTRACE_CURRENT_THREAD, 2)); ASSERT_TRUE(ign2.backtrace != NULL); VerifyIgnoreFrames(all.backtrace, ign1.backtrace, ign2.backtrace, @@ -296,7 +301,7 @@ TEST(libbacktrace, ptrace_trace) { ASSERT_NE(test_level_one(1, 2, 3, 4, NULL, NULL), 0); exit(1); } - VerifyProcTest(pid, BACKTRACE_NO_TID, ReadyLevelBacktrace, VerifyLevelDump); + VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, ReadyLevelBacktrace, VerifyLevelDump); kill(pid, SIGKILL); int status; @@ -309,7 +314,7 @@ TEST(libbacktrace, ptrace_max_trace) { ASSERT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, NULL, NULL), 0); exit(1); } - VerifyProcTest(pid, BACKTRACE_NO_TID, ReadyMaxBacktrace, VerifyMaxDump); + VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, ReadyMaxBacktrace, VerifyMaxDump); kill(pid, SIGKILL); int status; @@ -320,11 +325,11 @@ void VerifyProcessIgnoreFrames(const backtrace_t* bt_all) { pid_t pid = bt_all->pid; backtrace_context_t ign1; - ASSERT_TRUE(backtrace_create_context(&ign1, pid, BACKTRACE_NO_TID, 1)); + ASSERT_TRUE(backtrace_create_context(&ign1, pid, BACKTRACE_CURRENT_THREAD, 1)); ASSERT_TRUE(ign1.backtrace != NULL); backtrace_context_t ign2; - ASSERT_TRUE(backtrace_create_context(&ign2, pid, BACKTRACE_NO_TID, 2)); + ASSERT_TRUE(backtrace_create_context(&ign2, pid, BACKTRACE_CURRENT_THREAD, 2)); ASSERT_TRUE(ign2.backtrace != NULL); VerifyIgnoreFrames(bt_all, ign1.backtrace, ign2.backtrace, NULL); @@ -339,7 +344,7 @@ TEST(libbacktrace, ptrace_ignore_frames) { ASSERT_NE(test_level_one(1, 2, 3, 4, NULL, NULL), 0); exit(1); } - VerifyProcTest(pid, BACKTRACE_NO_TID, ReadyLevelBacktrace, VerifyProcessIgnoreFrames); + VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, ReadyLevelBacktrace, VerifyProcessIgnoreFrames); kill(pid, SIGKILL); int status; @@ -614,10 +619,12 @@ TEST(libbacktrace, thread_multiple_dump) { TEST(libbacktrace, format_test) { backtrace_context_t context; - ASSERT_TRUE(backtrace_create_context(&context, BACKTRACE_CURRENT_PROCESS, BACKTRACE_NO_TID, 0)); + ASSERT_TRUE(backtrace_create_context(&context, BACKTRACE_CURRENT_PROCESS, + BACKTRACE_CURRENT_THREAD, 0)); ASSERT_TRUE(context.backtrace != NULL); - backtrace_frame_data_t* frame = const_cast<backtrace_frame_data_t*>(&context.backtrace->frames[1]); + backtrace_frame_data_t* frame = + const_cast<backtrace_frame_data_t*>(&context.backtrace->frames[1]); backtrace_frame_data_t save_frame = *frame; memset(frame, 0, sizeof(backtrace_frame_data_t)); diff --git a/libcorkscrew/arch-arm/backtrace-arm.c b/libcorkscrew/arch-arm/backtrace-arm.c index ff6c192..7bd0d8f 100644 --- a/libcorkscrew/arch-arm/backtrace-arm.c +++ b/libcorkscrew/arch-arm/backtrace-arm.c @@ -59,7 +59,7 @@ #include <limits.h> #include <errno.h> #include <sys/ptrace.h> -#include <sys/exec_elf.h> +#include <elf.h> #include <cutils/log.h> #if !defined(__BIONIC_HAVE_UCONTEXT_T) diff --git a/libcorkscrew/arch-arm/ptrace-arm.c b/libcorkscrew/arch-arm/ptrace-arm.c index 78a9ea9..a50844e 100644 --- a/libcorkscrew/arch-arm/ptrace-arm.c +++ b/libcorkscrew/arch-arm/ptrace-arm.c @@ -19,7 +19,7 @@ #include "../ptrace-arch.h" -#include <sys/exec_elf.h> +#include <elf.h> #include <cutils/log.h> #ifndef PT_ARM_EXIDX diff --git a/libcutils/debugger.c b/libcutils/debugger.c index 9425006..7d907fc 100644 --- a/libcutils/debugger.c +++ b/libcutils/debugger.c @@ -30,6 +30,7 @@ int dump_tombstone(pid_t tid, char* pathbuf, size_t pathlen) { debugger_msg_t msg; msg.tid = tid; msg.action = DEBUGGER_ACTION_DUMP_TOMBSTONE; + msg.abort_msg_address = 0; int result = 0; if (TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg))) != sizeof(msg)) { @@ -63,6 +64,7 @@ int dump_backtrace_to_file(pid_t tid, int fd) { debugger_msg_t msg; msg.tid = tid; msg.action = DEBUGGER_ACTION_DUMP_BACKTRACE; + msg.abort_msg_address = 0; int result = 0; if (TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg))) != sizeof(msg)) { diff --git a/libutils/Android.mk b/libutils/Android.mk index 720443e..1710d36 100644 --- a/libutils/Android.mk +++ b/libutils/Android.mk @@ -116,10 +116,12 @@ LOCAL_STATIC_LIBRARIES := \ libcutils LOCAL_SHARED_LIBRARIES := \ - libcorkscrew \ + libbacktrace \ liblog \ libdl +include external/stlport/libstlport.mk + LOCAL_MODULE:= libutils include $(BUILD_STATIC_LIBRARY) @@ -129,10 +131,12 @@ include $(CLEAR_VARS) LOCAL_MODULE:= libutils LOCAL_WHOLE_STATIC_LIBRARIES := libutils LOCAL_SHARED_LIBRARIES := \ - liblog \ + libbacktrace \ libcutils \ libdl \ - libcorkscrew + liblog \ + +include external/stlport/libstlport.mk include $(BUILD_SHARED_LIBRARY) diff --git a/libutils/CallStack.cpp b/libutils/CallStack.cpp index 4ceaa7c..0bfb520 100644 --- a/libutils/CallStack.cpp +++ b/libutils/CallStack.cpp @@ -20,93 +20,33 @@ #include <utils/Printer.h> #include <utils/Errors.h> #include <utils/Log.h> -#include <corkscrew/backtrace.h> +#include <UniquePtr.h> + +#include <backtrace/Backtrace.h> namespace android { -CallStack::CallStack() : - mCount(0) { +CallStack::CallStack() { } -CallStack::CallStack(const char* logtag, int32_t ignoreDepth, int32_t maxDepth) { - this->update(ignoreDepth+1, maxDepth, CURRENT_THREAD); +CallStack::CallStack(const char* logtag, int32_t ignoreDepth) { + this->update(ignoreDepth+1); this->log(logtag); } -CallStack::CallStack(const CallStack& rhs) : - mCount(rhs.mCount) { - if (mCount) { - memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)); - } -} - CallStack::~CallStack() { } -CallStack& CallStack::operator = (const CallStack& rhs) { - mCount = rhs.mCount; - if (mCount) { - memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)); - } - return *this; -} - -bool CallStack::operator == (const CallStack& rhs) const { - if (mCount != rhs.mCount) - return false; - return !mCount || memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) == 0; -} - -bool CallStack::operator != (const CallStack& rhs) const { - return !operator == (rhs); -} - -bool CallStack::operator < (const CallStack& rhs) const { - if (mCount != rhs.mCount) - return mCount < rhs.mCount; - return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) < 0; -} +void CallStack::update(int32_t ignoreDepth, pid_t tid) { + mFrameLines.clear(); -bool CallStack::operator >= (const CallStack& rhs) const { - return !operator < (rhs); -} - -bool CallStack::operator > (const CallStack& rhs) const { - if (mCount != rhs.mCount) - return mCount > rhs.mCount; - return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) > 0; -} - -bool CallStack::operator <= (const CallStack& rhs) const { - return !operator > (rhs); -} - -const void* CallStack::operator [] (int index) const { - if (index >= int(mCount)) - return 0; - return reinterpret_cast<const void*>(mStack[index].absolute_pc); -} - -void CallStack::clear() { - mCount = 0; -} - -void CallStack::update(int32_t ignoreDepth, int32_t maxDepth, pid_t tid) { - if (maxDepth > MAX_DEPTH) { - maxDepth = MAX_DEPTH; + UniquePtr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, tid)); + if (!backtrace->Unwind(ignoreDepth)) { + ALOGW("%s: Failed to unwind callstack.", __FUNCTION__); } - ssize_t count; - - if (tid >= 0) { - count = unwind_backtrace_thread(tid, mStack, ignoreDepth + 1, maxDepth); - } else if (tid == CURRENT_THREAD) { - count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth); - } else { - ALOGE("%s: Invalid tid specified (%d)", __FUNCTION__, tid); - count = 0; + for (size_t i = 0; i < backtrace->NumFrames(); i++) { + mFrameLines.push_back(String8(backtrace->FormatFrameData(i).c_str())); } - - mCount = count > 0 ? count : 0; } void CallStack::log(const char* logtag, android_LogPriority priority, const char* prefix) const { @@ -129,16 +69,9 @@ String8 CallStack::toString(const char* prefix) const { } void CallStack::print(Printer& printer) const { - backtrace_symbol_t symbols[mCount]; - - get_backtrace_symbols(mStack, mCount, symbols); - for (size_t i = 0; i < mCount; i++) { - char line[MAX_BACKTRACE_LINE_LENGTH]; - format_backtrace_line(i, &mStack[i], &symbols[i], - line, MAX_BACKTRACE_LINE_LENGTH); - printer.printLine(line); + for (size_t i = 0; i < mFrameLines.size(); i++) { + printer.printLine(mFrameLines[i]); } - free_backtrace_symbols(symbols, mCount); } }; // namespace android diff --git a/libutils/Printer.cpp b/libutils/Printer.cpp index ac729e0..263e740 100644 --- a/libutils/Printer.cpp +++ b/libutils/Printer.cpp @@ -145,6 +145,7 @@ void String8Printer::printLine(const char* string) { return; } + mTarget->append(mPrefix); mTarget->append(string); mTarget->append("\n"); } diff --git a/libutils/ProcessCallStack.cpp b/libutils/ProcessCallStack.cpp index f9340c5..f837bcb 100644 --- a/libutils/ProcessCallStack.cpp +++ b/libutils/ProcessCallStack.cpp @@ -123,7 +123,7 @@ void ProcessCallStack::clear() { mTimeUpdated = tm(); } -void ProcessCallStack::update(int32_t maxDepth) { +void ProcessCallStack::update() { DIR *dp; struct dirent *ep; struct dirent entry; @@ -181,14 +181,13 @@ void ProcessCallStack::update(int32_t maxDepth) { int ignoreDepth = (selfPid == tid) ? IGNORE_DEPTH_CURRENT_THREAD : 0; // Update thread's call stacks - CallStack& cs = threadInfo.callStack; - cs.update(ignoreDepth, maxDepth, tid); + threadInfo.callStack.update(ignoreDepth, tid); // Read/save thread name threadInfo.threadName = getThreadName(tid); ALOGV("%s: Got call stack for tid %d (size %zu)", - __FUNCTION__, tid, cs.size()); + __FUNCTION__, tid, threadInfo.callStack.size()); } if (code != 0) { // returns positive error value on error ALOGE("%s: Failed to readdir from %s (errno = %d, '%s')", @@ -221,13 +220,12 @@ void ProcessCallStack::printInternal(Printer& printer, Printer& csPrinter) const for (size_t i = 0; i < mThreadMap.size(); ++i) { pid_t tid = mThreadMap.keyAt(i); const ThreadInfo& threadInfo = mThreadMap.valueAt(i); - const CallStack& cs = threadInfo.callStack; const String8& threadName = threadInfo.threadName; printer.printLine(""); printer.printFormatLine("\"%s\" sysTid=%d", threadName.string(), tid); - cs.print(csPrinter); + threadInfo.callStack.print(csPrinter); } dumpProcessFooter(printer, getpid()); diff --git a/rootdir/init.rc b/rootdir/init.rc index 1129206..95ca6af 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -257,6 +257,7 @@ on post-fs-data # create directory for MediaDrm plug-ins - give drm the read/write access to # the following directory. mkdir /data/mediadrm 0770 mediadrm mediadrm + restorecon_recursive /data/mediadrm # symlink to bugreport storage location symlink /data/data/com.android.shell/files/bugreports /data/bugreports diff --git a/rootdir/init.trace.rc b/rootdir/init.trace.rc index 8a05fd0..50944e6 100644 --- a/rootdir/init.trace.rc +++ b/rootdir/init.trace.rc @@ -9,6 +9,7 @@ on boot chown root shell /sys/kernel/debug/tracing/trace_clock chown root shell /sys/kernel/debug/tracing/buffer_size_kb chown root shell /sys/kernel/debug/tracing/options/overwrite + chown root shell /sys/kernel/debug/tracing/options/print-tgid chown root shell /sys/kernel/debug/tracing/events/sched/sched_switch/enable chown root shell /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable chown root shell /sys/kernel/debug/tracing/events/power/cpu_frequency/enable @@ -20,6 +21,7 @@ on boot chmod 0664 /sys/kernel/debug/tracing/trace_clock chmod 0664 /sys/kernel/debug/tracing/buffer_size_kb chmod 0664 /sys/kernel/debug/tracing/options/overwrite + chmod 0664 /sys/kernel/debug/tracing/options/print-tgid chmod 0664 /sys/kernel/debug/tracing/events/sched/sched_switch/enable chmod 0664 /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable chmod 0664 /sys/kernel/debug/tracing/events/power/cpu_frequency/enable diff --git a/toolbox/date.c b/toolbox/date.c index ed307c0..d6c9052 100644 --- a/toolbox/date.c +++ b/toolbox/date.c @@ -16,7 +16,7 @@ static int settime_alarm(struct timespec *ts) { if (fd < 0) return fd; - ret = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts); + ret = ioctl(fd, ANDROID_ALARM_SET_RTC, ts); close(fd); return ret; } |