diff options
Diffstat (limited to 'base/debug_util_posix.cc')
-rw-r--r-- | base/debug_util_posix.cc | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/base/debug_util_posix.cc b/base/debug_util_posix.cc index 60e2ff5..ced59c8 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"; + } + } +} |