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