summaryrefslogtreecommitdiffstats
path: root/debuggerd/backtrace.cpp
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2014-01-10 16:33:16 -0800
committerChristopher Ferris <cferris@google.com>2014-01-13 14:21:52 -0800
commit20303f856f1f1cdb5af58af0b116b8c598f0ea5c (patch)
treede0b205001d3afdf97bd54e4ee39a81750e9bf70 /debuggerd/backtrace.cpp
parente76343ef72458aff8fdc25c57f4e84407c05a2f2 (diff)
downloadsystem_core-20303f856f1f1cdb5af58af0b116b8c598f0ea5c.zip
system_core-20303f856f1f1cdb5af58af0b116b8c598f0ea5c.tar.gz
system_core-20303f856f1f1cdb5af58af0b116b8c598f0ea5c.tar.bz2
Next phase of the move, reformat use C++ features.
Use the libbacktrace C++ interface instead of the C interface in debuggerd. Reformat the debuggerd code to be closer to Google C++ style. Fix all debuggerd casts to be C++ casts. Add a frame number to the frame data structure for ease of formatting and add another FormatFrameData function. Change the format_test to use the new FormatFrameData function. Modify all of the backtrace_test to use the C++ interface. Change-Id: I10e1610861acf7f4a3ad53276b74971cfbfda464
Diffstat (limited to 'debuggerd/backtrace.cpp')
-rw-r--r--debuggerd/backtrace.cpp182
1 files changed, 88 insertions, 94 deletions
diff --git a/debuggerd/backtrace.cpp b/debuggerd/backtrace.cpp
index aa7a3c2..d388348 100644
--- a/debuggerd/backtrace.cpp
+++ b/debuggerd/backtrace.cpp
@@ -15,7 +15,6 @@
*/
#include <stddef.h>
-#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -27,121 +26,116 @@
#include <sys/types.h>
#include <sys/ptrace.h>
-#include <backtrace/backtrace.h>
+#include <backtrace/Backtrace.h>
+#include <UniquePtr.h>
#include "backtrace.h"
#include "utility.h"
static void dump_process_header(log_t* log, pid_t pid) {
- char path[PATH_MAX];
- char procnamebuf[1024];
- char* procname = NULL;
- FILE* fp;
-
- snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
- if ((fp = fopen(path, "r"))) {
- procname = fgets(procnamebuf, sizeof(procnamebuf), fp);
- fclose(fp);
- }
-
- time_t t = time(NULL);
- struct tm tm;
- localtime_r(&t, &tm);
- char timestr[64];
- strftime(timestr, sizeof(timestr), "%F %T", &tm);
- _LOG(log, SCOPE_AT_FAULT, "\n\n----- pid %d at %s -----\n", pid, timestr);
-
- if (procname) {
- _LOG(log, SCOPE_AT_FAULT, "Cmd line: %s\n", procname);
- }
+ char path[PATH_MAX];
+ char procnamebuf[1024];
+ char* procname = NULL;
+ FILE* fp;
+
+ snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
+ if ((fp = fopen(path, "r"))) {
+ procname = fgets(procnamebuf, sizeof(procnamebuf), fp);
+ fclose(fp);
+ }
+
+ time_t t = time(NULL);
+ struct tm tm;
+ localtime_r(&t, &tm);
+ char timestr[64];
+ strftime(timestr, sizeof(timestr), "%F %T", &tm);
+ _LOG(log, SCOPE_AT_FAULT, "\n\n----- pid %d at %s -----\n", pid, timestr);
+
+ if (procname) {
+ _LOG(log, SCOPE_AT_FAULT, "Cmd line: %s\n", procname);
+ }
}
static void dump_process_footer(log_t* log, pid_t pid) {
- _LOG(log, SCOPE_AT_FAULT, "\n----- end %d -----\n", pid);
+ _LOG(log, SCOPE_AT_FAULT, "\n----- end %d -----\n", pid);
}
-static void dump_thread(log_t* log, pid_t tid, bool attached,
- bool* detach_failed, int* total_sleep_time_usec) {
- char path[PATH_MAX];
- char threadnamebuf[1024];
- char* threadname = NULL;
- FILE* fp;
-
- snprintf(path, sizeof(path), "/proc/%d/comm", tid);
- if ((fp = fopen(path, "r"))) {
- threadname = fgets(threadnamebuf, sizeof(threadnamebuf), fp);
- fclose(fp);
- if (threadname) {
- size_t len = strlen(threadname);
- if (len && threadname[len - 1] == '\n') {
- threadname[len - 1] = '\0';
- }
- }
+static void dump_thread(
+ log_t* log, pid_t tid, bool attached, bool* detach_failed, int* total_sleep_time_usec) {
+ char path[PATH_MAX];
+ char threadnamebuf[1024];
+ char* threadname = NULL;
+ FILE* fp;
+
+ snprintf(path, sizeof(path), "/proc/%d/comm", tid);
+ if ((fp = fopen(path, "r"))) {
+ threadname = fgets(threadnamebuf, sizeof(threadnamebuf), fp);
+ fclose(fp);
+ if (threadname) {
+ size_t len = strlen(threadname);
+ if (len && threadname[len - 1] == '\n') {
+ threadname[len - 1] = '\0';
+ }
}
+ }
- _LOG(log, SCOPE_AT_FAULT, "\n\"%s\" sysTid=%d\n",
- threadname ? threadname : "<unknown>", tid);
+ _LOG(log, SCOPE_AT_FAULT, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid);
- if (!attached && ptrace(PTRACE_ATTACH, tid, 0, 0) < 0) {
- _LOG(log, SCOPE_AT_FAULT, "Could not attach to thread: %s\n", strerror(errno));
- return;
- }
+ if (!attached && ptrace(PTRACE_ATTACH, tid, 0, 0) < 0) {
+ _LOG(log, SCOPE_AT_FAULT, "Could not attach to thread: %s\n", strerror(errno));
+ return;
+ }
- wait_for_stop(tid, total_sleep_time_usec);
+ wait_for_stop(tid, total_sleep_time_usec);
- backtrace_context_t context;
- if (!backtrace_create_context(&context, tid, -1, 0)) {
- _LOG(log, SCOPE_AT_FAULT, "Could not create backtrace context.\n");
- } else {
- dump_backtrace_to_log(&context, log, SCOPE_AT_FAULT, " ");
- backtrace_destroy_context(&context);
- }
+ UniquePtr<Backtrace> backtrace(Backtrace::Create(tid, BACKTRACE_CURRENT_THREAD));
+ if (backtrace->Unwind(0)) {
+ dump_backtrace_to_log(backtrace.get(), log, SCOPE_AT_FAULT, " ");
+ }
- if (!attached && ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
- LOG("ptrace detach from %d failed: %s\n", tid, strerror(errno));
- *detach_failed = true;
- }
+ if (!attached && ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
+ LOG("ptrace detach from %d failed: %s\n", tid, strerror(errno));
+ *detach_failed = true;
+ }
}
void dump_backtrace(int fd, int amfd, pid_t pid, pid_t tid, bool* detach_failed,
- int* total_sleep_time_usec) {
- log_t log;
- log.tfd = fd;
- log.amfd = amfd;
- log.quiet = true;
-
- dump_process_header(&log, pid);
- dump_thread(&log, tid, true, detach_failed, total_sleep_time_usec);
-
- char task_path[64];
- snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid);
- DIR* d = opendir(task_path);
- if (d != NULL) {
- struct dirent* de = NULL;
- while ((de = readdir(d)) != NULL) {
- if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
- continue;
- }
-
- char* end;
- pid_t new_tid = strtoul(de->d_name, &end, 10);
- if (*end || new_tid == tid) {
- continue;
- }
-
- dump_thread(&log, new_tid, false, detach_failed, total_sleep_time_usec);
- }
- closedir(d);
+ int* total_sleep_time_usec) {
+ log_t log;
+ log.tfd = fd;
+ log.amfd = amfd;
+ log.quiet = true;
+
+ dump_process_header(&log, pid);
+ dump_thread(&log, tid, true, detach_failed, total_sleep_time_usec);
+
+ char task_path[64];
+ snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid);
+ DIR* d = opendir(task_path);
+ if (d != NULL) {
+ struct dirent* de = NULL;
+ while ((de = readdir(d)) != NULL) {
+ if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
+ continue;
+ }
+
+ char* end;
+ pid_t new_tid = strtoul(de->d_name, &end, 10);
+ if (*end || new_tid == tid) {
+ continue;
+ }
+
+ dump_thread(&log, new_tid, false, detach_failed, total_sleep_time_usec);
}
+ closedir(d);
+ }
- dump_process_footer(&log, pid);
+ dump_process_footer(&log, pid);
}
-void dump_backtrace_to_log(const backtrace_context_t* context, log_t* log,
+void dump_backtrace_to_log(Backtrace* backtrace, log_t* log,
int scope_flags, const char* prefix) {
- char buf[512];
- for (size_t i = 0; i < context->backtrace->num_frames; i++) {
- backtrace_format_frame_data(context, i, buf, sizeof(buf));
- _LOG(log, scope_flags, "%s%s\n", prefix, buf);
- }
+ for (size_t i = 0; i < backtrace->NumFrames(); i++) {
+ _LOG(log, scope_flags, "%s%s\n", prefix, backtrace->FormatFrameData(i).c_str());
+ }
}