| OLD | NEW | 
|    1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |    1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "base/debug/stack_trace.h" |    5 #include "base/debug/stack_trace.h" | 
|    6  |    6  | 
|    7 #include <errno.h> |    7 #include <errno.h> | 
|    8 #include <execinfo.h> |    8 #include <execinfo.h> | 
|    9 #include <fcntl.h> |    9 #include <fcntl.h> | 
|   10 #include <stdio.h> |   10 #include <stdio.h> | 
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   98   } |   98   } | 
|   99  |   99  | 
|  100 #endif  // defined(__GLIBCXX__) |  100 #endif  // defined(__GLIBCXX__) | 
|  101 } |  101 } | 
|  102 #endif  // !defined(USE_SYMBOLIZE) |  102 #endif  // !defined(USE_SYMBOLIZE) | 
|  103  |  103  | 
|  104 // Gets the backtrace as a vector of strings. If possible, resolve symbol |  104 // Gets the backtrace as a vector of strings. If possible, resolve symbol | 
|  105 // names and attach these. Otherwise just use raw addresses. Returns true |  105 // names and attach these. Otherwise just use raw addresses. Returns true | 
|  106 // if any symbol name is resolved.  Returns false on error and *may* fill |  106 // if any symbol name is resolved.  Returns false on error and *may* fill | 
|  107 // in |error_message| if an error message is available. |  107 // in |error_message| if an error message is available. | 
|  108 bool GetBacktraceStrings(void **trace, int size, |  108 bool GetBacktraceStrings(void *const *trace, int size, | 
|  109                          std::vector<std::string>* trace_strings, |  109                          std::vector<std::string>* trace_strings, | 
|  110                          std::string* error_message) { |  110                          std::string* error_message) { | 
|  111   bool symbolized = false; |  111   bool symbolized = false; | 
|  112  |  112  | 
|  113 #if defined(USE_SYMBOLIZE) |  113 #if defined(USE_SYMBOLIZE) | 
|  114   for (int i = 0; i < size; ++i) { |  114   for (int i = 0; i < size; ++i) { | 
|  115     char symbol[1024]; |  115     char symbol[1024]; | 
|  116     // Subtract by one as return address of function may be in the next |  116     // Subtract by one as return address of function may be in the next | 
|  117     // function when a function is annotated as noreturn. |  117     // function when a function is annotated as noreturn. | 
|  118     if (google::Symbolize(static_cast<char *>(trace[i]) - 1, |  118     if (google::Symbolize(static_cast<char *>(trace[i]) - 1, | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  154   if (backtrace == NULL) { |  154   if (backtrace == NULL) { | 
|  155     count_ = 0; |  155     count_ = 0; | 
|  156     return; |  156     return; | 
|  157   } |  157   } | 
|  158 #endif |  158 #endif | 
|  159   // Though the backtrace API man page does not list any possible negative |  159   // Though the backtrace API man page does not list any possible negative | 
|  160   // return values, we take no chance. |  160   // return values, we take no chance. | 
|  161   count_ = std::max(backtrace(trace_, arraysize(trace_)), 0); |  161   count_ = std::max(backtrace(trace_, arraysize(trace_)), 0); | 
|  162 } |  162 } | 
|  163  |  163  | 
|  164 void StackTrace::PrintBacktrace() { |  164 void StackTrace::PrintBacktrace() const { | 
|  165 #if defined(OS_MACOSX) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 |  165 #if defined(OS_MACOSX) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | 
|  166   if (backtrace_symbols_fd == NULL) |  166   if (backtrace_symbols_fd == NULL) | 
|  167     return; |  167     return; | 
|  168 #endif |  168 #endif | 
|  169   fflush(stderr); |  169   fflush(stderr); | 
|  170   std::vector<std::string> trace_strings; |  170   std::vector<std::string> trace_strings; | 
|  171   GetBacktraceStrings(trace_, count_, &trace_strings, NULL); |  171   GetBacktraceStrings(trace_, count_, &trace_strings, NULL); | 
|  172   for (size_t i = 0; i < trace_strings.size(); ++i) { |  172   for (size_t i = 0; i < trace_strings.size(); ++i) { | 
|  173     std::cerr << "\t" << trace_strings[i] << "\n"; |  173     std::cerr << "\t" << trace_strings[i] << "\n"; | 
|  174   } |  174   } | 
|  175 } |  175 } | 
|  176  |  176  | 
|  177 void StackTrace::OutputToStream(std::ostream* os) { |  177 void StackTrace::OutputToStream(std::ostream* os) const { | 
|  178 #if defined(OS_MACOSX) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 |  178 #if defined(OS_MACOSX) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | 
|  179   if (backtrace_symbols == NULL) |  179   if (backtrace_symbols == NULL) | 
|  180     return; |  180     return; | 
|  181 #endif |  181 #endif | 
|  182   std::vector<std::string> trace_strings; |  182   std::vector<std::string> trace_strings; | 
|  183   std::string error_message; |  183   std::string error_message; | 
|  184   if (GetBacktraceStrings(trace_, count_, &trace_strings, &error_message)) { |  184   if (GetBacktraceStrings(trace_, count_, &trace_strings, &error_message)) { | 
|  185     (*os) << "Backtrace:\n"; |  185     (*os) << "Backtrace:\n"; | 
|  186   } else { |  186   } else { | 
|  187     if (!error_message.empty()) |  187     if (!error_message.empty()) | 
|  188       error_message = " (" + error_message + ")"; |  188       error_message = " (" + error_message + ")"; | 
|  189     (*os) << "Unable to get symbols for backtrace" << error_message << ". " |  189     (*os) << "Unable to get symbols for backtrace" << error_message << ". " | 
|  190           << "Dumping raw addresses in trace:\n"; |  190           << "Dumping raw addresses in trace:\n"; | 
|  191   } |  191   } | 
|  192  |  192  | 
|  193   for (size_t i = 0; i < trace_strings.size(); ++i) { |  193   for (size_t i = 0; i < trace_strings.size(); ++i) { | 
|  194     (*os) << "\t" << trace_strings[i] << "\n"; |  194     (*os) << "\t" << trace_strings[i] << "\n"; | 
|  195   } |  195   } | 
|  196 } |  196 } | 
|  197  |  197  | 
|  198 }  // namespace debug |  198 }  // namespace debug | 
|  199 }  // namespace base |  199 }  // namespace base | 
| OLD | NEW |