Home | History | Annotate | Download | only in base
      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 "&lt;" 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("&lt;");
     65         break;
     66 
     67       case '>':
     68         output->append("&gt;");
     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