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#ifndef BASE_LOCATION_H_ 6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define BASE_LOCATION_H_ 7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 8cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <stddef.h> 9cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko 10b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <cassert> 11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <string> 12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/base_export.h" 14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/containers/hash_tables.h" 15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace tracked_objects { 17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Location provides basic info where of an object was constructed, or was 19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// significantly brought to life. 20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass BASE_EXPORT Location { 21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public: 22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Constructor should be called with a long-lived char*, such as __FILE__. 23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // It assumes the provided value will persist as a global constant, and it 24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // will not make a copy of it. 25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Location(const char* function_name, 26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* file_name, 27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int line_number, 28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const void* program_counter); 29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Provide a default constructor for easy of debugging. 31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Location(); 32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Copy constructor. 34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Location(const Location& other); 35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Comparator for hash map insertion. 37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // No need to use |function_name_| since the other two fields uniquely 38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // identify this location. 39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool operator==(const Location& other) const { 40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return line_number_ == other.line_number_ && 41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat file_name_ == other.file_name_; 42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* function_name() const { return function_name_; } 45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* file_name() const { return file_name_; } 46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int line_number() const { return line_number_; } 47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const void* program_counter() const { return program_counter_; } 48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 49b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::string ToString() const; 50b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 51b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Hash operator for hash maps. 52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat struct Hash { 53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t operator()(const Location& location) const { 54b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Compute the hash value using file name pointer and line number. 55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // No need to use |function_name_| since the other two fields uniquely 56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // identify this location. 57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // The file name will always be uniquely identified by its pointer since 59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // it comes from __FILE__, so no need to check the contents of the string. 60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // See the definition of FROM_HERE in location.h, and how it is used 61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // elsewhere. 62cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko return base::HashPair(reinterpret_cast<uintptr_t>(location.file_name()), 63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat location.line_number()); 64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat }; 66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 67b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Translate the some of the state in this instance into a human readable 68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // string with HTML characters in the function names escaped, and append that 69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // string to |output|. Inclusion of the file_name_ and function_name_ are 70b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // optional, and controlled by the boolean arguments. 71b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void Write(bool display_filename, bool display_function_name, 72b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::string* output) const; 73b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 74b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Write function_name_ in HTML with '<' and '>' properly encoded. 75b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void WriteFunctionName(std::string* output) const; 76b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 77b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat private: 78b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* function_name_; 79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* file_name_; 80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int line_number_; 81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const void* program_counter_; 82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// A "snapshotted" representation of the Location class that can safely be 85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// passed across process boundaries. 86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstruct BASE_EXPORT LocationSnapshot { 87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // The default constructor is exposed to support the IPC serialization macros. 88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat LocationSnapshot(); 89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat explicit LocationSnapshot(const tracked_objects::Location& location); 90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ~LocationSnapshot(); 91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::string file_name; 93b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::string function_name; 94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int line_number; 95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 97b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT const void* GetProgramCounter(); 98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Define a macro to record the current source location. 100b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define FROM_HERE FROM_HERE_WITH_EXPLICIT_FUNCTION(__FUNCTION__) 101b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define FROM_HERE_WITH_EXPLICIT_FUNCTION(function_name) \ 103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ::tracked_objects::Location(function_name, \ 104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat __FILE__, \ 105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat __LINE__, \ 106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ::tracked_objects::GetProgramCounter()) 107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace tracked_objects 109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif // BASE_LOCATION_H_ 111