1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "build/build_config.h" 6 7 #if defined(COMPILER_MSVC) 8 #include <intrin.h> 9 #endif 10 11 #include "base/location.h" 12 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/stringprintf.h" 14 15 namespace tracked_objects { 16 17 Location::Location(const char* function_name, 18 const char* file_name, 19 int line_number, 20 const void* program_counter) 21 : function_name_(function_name), 22 file_name_(file_name), 23 line_number_(line_number), 24 program_counter_(program_counter) { 25 } 26 27 Location::Location() 28 : function_name_("Unknown"), 29 file_name_("Unknown"), 30 line_number_(-1), 31 program_counter_(NULL) { 32 } 33 34 Location::Location(const Location& other) 35 : function_name_(other.function_name_), 36 file_name_(other.file_name_), 37 line_number_(other.line_number_), 38 program_counter_(other.program_counter_) { 39 } 40 41 std::string Location::ToString() const { 42 return std::string(function_name_) + "@" + file_name_ + ":" + 43 base::IntToString(line_number_); 44 } 45 46 void Location::Write(bool display_filename, bool display_function_name, 47 std::string* output) const { 48 base::StringAppendF(output, "%s[%d] ", 49 display_filename ? file_name_ : "line", 50 line_number_); 51 52 if (display_function_name) { 53 WriteFunctionName(output); 54 output->push_back(' '); 55 } 56 } 57 58 void Location::WriteFunctionName(std::string* output) const { 59 // Translate "<" to "<" for HTML safety. 60 // TODO(jar): Support ASCII or html for logging in ASCII. 61 for (const char *p = function_name_; *p; p++) { 62 switch (*p) { 63 case '<': 64 output->append("<"); 65 break; 66 67 case '>': 68 output->append(">"); 69 break; 70 71 default: 72 output->push_back(*p); 73 break; 74 } 75 } 76 } 77 78 //------------------------------------------------------------------------------ 79 LocationSnapshot::LocationSnapshot() : line_number(-1) { 80 } 81 82 LocationSnapshot::LocationSnapshot( 83 const tracked_objects::Location& location) 84 : file_name(location.file_name()), 85 function_name(location.function_name()), 86 line_number(location.line_number()) { 87 } 88 89 LocationSnapshot::~LocationSnapshot() { 90 } 91 92 //------------------------------------------------------------------------------ 93 #if defined(COMPILER_MSVC) 94 __declspec(noinline) 95 #endif 96 BASE_EXPORT const void* GetProgramCounter() { 97 #if defined(COMPILER_MSVC) 98 return _ReturnAddress(); 99 #elif defined(COMPILER_GCC) && !defined(OS_NACL) 100 return __builtin_extract_return_addr(__builtin_return_address(0)); 101 #else 102 return NULL; 103 #endif 104 } 105 106 } // namespace tracked_objects 107