michael@0: // Copyright (c) 2012 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #include "build/build_config.h" michael@0: michael@0: #if defined(COMPILER_MSVC) michael@0: // MSDN says to #include , but that breaks the VS2005 build. michael@0: extern "C" { michael@0: void* _ReturnAddress(); michael@0: } michael@0: #endif michael@0: michael@0: #include "base/location.h" michael@0: #include "base/strings/string_number_conversions.h" michael@0: #include "base/strings/stringprintf.h" michael@0: michael@0: namespace tracked_objects { michael@0: michael@0: Location::Location(const char* function_name, michael@0: const char* file_name, michael@0: int line_number, michael@0: const void* program_counter) michael@0: : function_name_(function_name), michael@0: file_name_(file_name), michael@0: line_number_(line_number), michael@0: program_counter_(program_counter) { michael@0: } michael@0: michael@0: Location::Location() michael@0: : function_name_("Unknown"), michael@0: file_name_("Unknown"), michael@0: line_number_(-1), michael@0: program_counter_(NULL) { michael@0: } michael@0: michael@0: std::string Location::ToString() const { michael@0: return std::string(function_name_) + "@" + file_name_ + ":" + michael@0: base::IntToString(line_number_); michael@0: } michael@0: michael@0: void Location::Write(bool display_filename, bool display_function_name, michael@0: std::string* output) const { michael@0: base::StringAppendF(output, "%s[%d] ", michael@0: display_filename ? file_name_ : "line", michael@0: line_number_); michael@0: michael@0: if (display_function_name) { michael@0: WriteFunctionName(output); michael@0: output->push_back(' '); michael@0: } michael@0: } michael@0: michael@0: void Location::WriteFunctionName(std::string* output) const { michael@0: // Translate "<" to "<" for HTML safety. michael@0: // TODO(jar): Support ASCII or html for logging in ASCII. michael@0: for (const char *p = function_name_; *p; p++) { michael@0: switch (*p) { michael@0: case '<': michael@0: output->append("<"); michael@0: break; michael@0: michael@0: case '>': michael@0: output->append(">"); michael@0: break; michael@0: michael@0: default: michael@0: output->push_back(*p); michael@0: break; michael@0: } michael@0: } michael@0: } michael@0: michael@0: //------------------------------------------------------------------------------ michael@0: LocationSnapshot::LocationSnapshot() : line_number(-1) { michael@0: } michael@0: michael@0: LocationSnapshot::LocationSnapshot( michael@0: const tracked_objects::Location& location) michael@0: : file_name(location.file_name()), michael@0: function_name(location.function_name()), michael@0: line_number(location.line_number()) { michael@0: } michael@0: michael@0: LocationSnapshot::~LocationSnapshot() { michael@0: } michael@0: michael@0: //------------------------------------------------------------------------------ michael@0: #if defined(COMPILER_MSVC) michael@0: __declspec(noinline) michael@0: #endif michael@0: BASE_EXPORT const void* GetProgramCounter() { michael@0: #if defined(COMPILER_MSVC) michael@0: return _ReturnAddress(); michael@0: #elif defined(COMPILER_GCC) michael@0: return __builtin_extract_return_addr(__builtin_return_address(0)); michael@0: #endif // COMPILER_GCC michael@0: michael@0: return NULL; michael@0: } michael@0: michael@0: } // namespace tracked_objects