From 96fd00320f4eef1cc52f68939f86b319f6d2095f Mon Sep 17 00:00:00 2001 From: "ajwong@chromium.org" Date: Fri, 24 Apr 2009 00:13:08 +0000 Subject: Print backtraces on FATAL log messages in debug mode. This provides basic support for looking up backtrace information on GNU libc systems and in Windows. The code is only enabled for FATAL log messages in debug mode. In a release build, it is unlikely that symbols will be available making the backtrace less useful. Review URL: http://codereview.chromium.org/62140 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14391 0039d316-1c4b-4281-b951-d872f2087c98 --- base/debug_util_posix.cc | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'base/debug_util_posix.cc') 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 #include #include #include @@ -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 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"; + } + } +} -- cgit v1.1