Index: base/debug_util_posix.cc |
diff --git a/base/debug_util_posix.cc b/base/debug_util_posix.cc |
index 60e2ff593b090db34b9bef967dbc06bd0180ed47..ced59c82e3e9ad8fa9bee17db3116cf07ff41b65 100644 |
--- a/base/debug_util_posix.cc |
+++ b/base/debug_util_posix.cc |
@@ -1,10 +1,11 @@ |
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
#include "build/build_config.h" |
#include "base/debug_util.h" |
+#include <errno.h> |
#include <execinfo.h> |
#include <fcntl.h> |
#include <stdio.h> |
@@ -15,6 +16,7 @@ |
#include "base/basictypes.h" |
#include "base/logging.h" |
+#include "base/scoped_ptr.h" |
#include "base/string_piece.h" |
// static |
@@ -109,15 +111,43 @@ void DebugUtil::BreakDebugger() { |
} |
StackTrace::StackTrace() { |
- static const int kMaxCallers = 256; |
+ const int kMaxCallers = 256; |
void* callers[kMaxCallers]; |
int count = backtrace(callers, kMaxCallers); |
- trace_.resize(count); |
- memcpy(&trace_[0], callers, sizeof(void*) * count); |
+ |
+ // Though the backtrace API man page does not list any possible negative |
+ // return values, we still still exclude them because they would break the |
+ // memcpy code below. |
+ if (count > 0) { |
+ trace_.resize(count); |
+ memcpy(&trace_[0], callers, sizeof(callers[0]) * count); |
+ } else { |
+ trace_.resize(0); |
+ } |
} |
void StackTrace::PrintBacktrace() { |
fflush(stderr); |
backtrace_symbols_fd(&trace_[0], trace_.size(), STDERR_FILENO); |
} |
+ |
+void StackTrace::OutputToStream(std::ostream* os) { |
+ scoped_ptr_malloc<char*> trace_symbols( |
+ backtrace_symbols(&trace_[0], trace_.size())); |
+ |
+ // If we can't retrieve the symbols, print an error and just dump the raw |
+ // addresses. |
+ if (trace_symbols.get() == NULL) { |
+ (*os) << "Unable get symbols for backtrace (" << strerror(errno) |
+ << "). Dumping raw addresses in trace:\n"; |
+ for (size_t i = 0; i < trace_.size(); ++i) { |
+ (*os) << "\t" << trace_[i] << "\n"; |
+ } |
+ } else { |
+ (*os) << "Backtrace:\n"; |
+ for (size_t i = 0; i < trace_.size(); ++i) { |
+ (*os) << "\t" << trace_symbols.get()[i] << "\n"; |
+ } |
+ } |
+} |