MySQL 9.6.0
Source Code Documentation
object_lifetime_tracker.h
Go to the documentation of this file.
1// Copyright (c) 2025, Oracle and/or its affiliates.
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License, version 2.0,
5// as published by the Free Software Foundation.
6//
7// This program is designed to work with certain software (including
8// but not limited to OpenSSL) that is licensed under separate terms,
9// as designated in a particular file or component or in included license
10// documentation. The authors of MySQL hereby grant you an additional
11// permission to link the program and your derivative works with the
12// separately licensed software that they have either included with
13// the program or referenced in the documentation.
14//
15// This program is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License, version 2.0, for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with this program; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
24#ifndef MYSQL_DEBUGGING_OBJECT_LIFETIME_TRACKER_H
25#define MYSQL_DEBUGGING_OBJECT_LIFETIME_TRACKER_H
26
27/// @file
28/// Experimental API header
29
30#include <atomic> // atomic
31#include <iostream> // cout
32#include <string_view> // string_view
33
34/// @addtogroup GroupLibsMysqlDebugging
35/// @{
36
38
39/// Integral type used to uniquely identify objects.
40using Tracker_id = int;
41
42/// The value to use for m_id next time we construct an Allocator.
43///
44/// Not a member variable of Object_lifetime_tracker because we need one global
45/// instance, not one per specialization.
46///
47/// @tparam channel Identifies a unique sequence of object ids.
48template <int channel = 0>
50 static std::atomic<Tracker_id> tracker_id_counter = 0;
51 Tracker_id ret = tracker_id_counter.fetch_add(1);
52 return ret;
53}
54
55/// Return the name of the given type (not demangled).
56template <class Type>
57[[nodiscard]] std::string_view type_name() {
58 return typeid(Type).name();
59}
60
61/// Debug facility to log constructor/assignment/destructor usage for a class.
62///
63/// To make a class log such life cycle events, make it inherit from this class.
64///
65/// This is only for temporary use in debugging sessions and must never be used
66/// in released code (not even debug-only code). It is intended to aid in
67/// debugging memory related issues, such as objects used after destruction. It
68/// writes a line to stdout for every object life cycle event: to keep the
69/// output size manageable it is usually good to minimize the amount of
70/// problematic code before using this class.
71///
72/// @tparam Self_tp If given, log entries for constructor invocations will be
73/// annotated with the type name of this class.
74template <class Self_tp = void>
76 // True if the type of the subclass was specified as template argument.
77 static constexpr bool known_type = !std::same_as<Self_tp, void>;
78
79 // Use ANSI colors for a more readable log.
80 static constexpr const char *m_reset = "\033[30m";
81 static constexpr const char *m_red = "\033[31m";
82 static constexpr const char *m_green = "\033[32m";
83 static constexpr const char *m_yellow = "\033[33m";
84 static constexpr const char *m_blue = "\033[34m";
85 static constexpr const char *m_magenta = "\033[35m";
86 static constexpr const char *m_cyan = "\033[36m";
87 static constexpr const char *grey = "\033[37m";
88
89 public:
90 /// Default constructor.
92 log_construct("Default");
93 }
94
95 /// Construct using the message "FLAVOR-construct".
96 ///
97 /// This is usable in custom subclass constructors.
98 explicit Object_lifetime_tracker(std::string_view flavor) noexcept
100 log_construct(flavor);
101 }
102
103 /// Construct using the message "FLAVOR-construct from SOURCE".
104 ///
105 /// This is usable in custom subclass constructors.
106 explicit Object_lifetime_tracker(std::string_view flavor,
109 log_construct_from(flavor, source);
110 }
111
112 /// Copy-construct using the message "Copy-construct from ID".
113 ///
114 /// This will be called when the subclass is copy-constructed, unless the
115 /// subclass copy constructor explicitly invokes another constructor in this
116 /// class.
119 log_construct_from("Copy", other.m_id);
120 }
121
122 /// Copy-construct using the message "Move-construct from ID".
123 ///
124 /// This will be called when the subclass is move-constructed, unless the
125 /// subclass move constructor explicitly invokes another constructor in this
126 /// class.
129 log_construct_from("Move", other.m_id);
130 log_move(other.m_id);
131 }
132
133 /// Copy-construct using the message "Copy-assign from ID".
134 ///
135 /// This will be called when the subclass is copy-assigned to.
136 // NOLINTNEXTLINE(cert-oop54-cpp)
138 const Object_lifetime_tracker &other) noexcept {
139 log_assign("Copy", other.m_id);
140 return *this;
141 }
142
143 /// Move-construct using the message "Move-assign from ID".
144 ///
145 /// This will be called when the subclass is move-assigned to.
147 log_assign("Move", other.m_id);
148 log_move(other.m_id);
149 return *this;
150 }
151
152 /// Destruct using the message "Destruct".
154
155 /// Write a message to the log.
156 ///
157 /// The parameters will be passed to a std::stringstream using operator<<.
158 void log(const auto &...args) const { log_for(m_id, args...); }
159
160 /// Write a message to the log, on behalf of another object having the given
161 /// ID.
162 ///
163 /// The parameters will be passed to a std::stringstream using operator<<.
164 void log_for(const auto &id, const auto &...args) const {
165 do_log(id, ": ", args..., "\n");
166 }
167
168 /// Return the ID for this object.
169 [[nodiscard]] Tracker_id tracker_id() const { return m_id; }
170
171 /// Return the type of this object (not demangled).
172 [[nodiscard]] std::string_view type_name() const {
173 if constexpr (known_type) {
174 return type_name<Self_tp>();
175 } else {
176 return "?";
177 }
178 }
179
180 private:
181 /// Write a message during object construction.
182 void log_construct(std::string_view flavor) const {
183 if constexpr (known_type) {
184 log(m_green, flavor, "-construct", m_reset, " (", this->type_name(), ")");
185 } else {
186 log(m_green, flavor, "-construct", m_reset);
187 }
188 }
189
190 /// Write a message during object construction, including a " from SOURCE"
191 /// text.
192 void log_construct_from(std::string_view flavor, Tracker_id source) const {
193 if constexpr (known_type) {
194 log(m_green, flavor, "-construct", m_reset, " from ", source, " (",
195 this->type_name(), ")");
196 } else {
197 log(m_green, flavor, "-construct", m_reset, " from ", source);
198 }
199 }
200
201 /// Write a message during object assignment.
202 void log_assign(std::string_view flavor, Tracker_id source) const {
203 log(m_cyan, flavor, "-assign", m_reset, " from ", source);
204 }
205
206 /// Write a message on behalf of a moved-from object.
207 void log_move(Tracker_id id) const {
208 log_for(id, m_magenta, "Move-from", m_reset);
209 }
210
211 /// Low level to log any message.
212 void do_log(const auto &...args) const {
213 (std::cout << ... << args);
214 std::cout.flush();
215 }
216
217 // Integer representing object "identity". Each object has a distinct value
218 // for m_id.
220}; // class Object_lifetime_tracker
221
222} // namespace mysql::debugging
223
224// addtogroup GroupLibsMysqlDebugging
225/// @}
226
227#endif // ifndef MYSQL_DEBUGGING_OBJECT_LIFETIME_TRACKER_H
Debug facility to log constructor/assignment/destructor usage for a class.
Definition: object_lifetime_tracker.h:75
Object_lifetime_tracker(Object_lifetime_tracker &&other) noexcept
Copy-construct using the message "Move-construct from ID".
Definition: object_lifetime_tracker.h:127
void log_move(Tracker_id id) const
Write a message on behalf of a moved-from object.
Definition: object_lifetime_tracker.h:207
Object_lifetime_tracker() noexcept
Default constructor.
Definition: object_lifetime_tracker.h:91
Object_lifetime_tracker & operator=(Object_lifetime_tracker &&other) noexcept
Move-construct using the message "Move-assign from ID".
Definition: object_lifetime_tracker.h:146
void log_assign(std::string_view flavor, Tracker_id source) const
Write a message during object assignment.
Definition: object_lifetime_tracker.h:202
static constexpr const char * m_magenta
Definition: object_lifetime_tracker.h:85
Tracker_id tracker_id() const
Return the ID for this object.
Definition: object_lifetime_tracker.h:169
void log_construct_from(std::string_view flavor, Tracker_id source) const
Write a message during object construction, including a " from SOURCE" text.
Definition: object_lifetime_tracker.h:192
static constexpr const char * m_cyan
Definition: object_lifetime_tracker.h:86
Object_lifetime_tracker(std::string_view flavor, Tracker_id source) noexcept
Construct using the message "FLAVOR-construct from SOURCE".
Definition: object_lifetime_tracker.h:106
std::string_view type_name() const
Return the type of this object (not demangled).
Definition: object_lifetime_tracker.h:172
Object_lifetime_tracker & operator=(const Object_lifetime_tracker &other) noexcept
Copy-construct using the message "Copy-assign from ID".
Definition: object_lifetime_tracker.h:137
void log(const auto &...args) const
Write a message to the log.
Definition: object_lifetime_tracker.h:158
~Object_lifetime_tracker() noexcept
Destruct using the message "Destruct".
Definition: object_lifetime_tracker.h:153
static constexpr const char * m_blue
Definition: object_lifetime_tracker.h:84
Object_lifetime_tracker(std::string_view flavor) noexcept
Construct using the message "FLAVOR-construct".
Definition: object_lifetime_tracker.h:98
Tracker_id m_id
Definition: object_lifetime_tracker.h:219
static constexpr bool known_type
Definition: object_lifetime_tracker.h:77
static constexpr const char * m_red
Definition: object_lifetime_tracker.h:81
void log_construct(std::string_view flavor) const
Write a message during object construction.
Definition: object_lifetime_tracker.h:182
void do_log(const auto &...args) const
Low level to log any message.
Definition: object_lifetime_tracker.h:212
static constexpr const char * m_green
Definition: object_lifetime_tracker.h:82
static constexpr const char * m_yellow
Definition: object_lifetime_tracker.h:83
void log_for(const auto &id, const auto &...args) const
Write a message to the log, on behalf of another object having the given ID.
Definition: object_lifetime_tracker.h:164
static constexpr const char * grey
Definition: object_lifetime_tracker.h:87
static constexpr const char * m_reset
Definition: object_lifetime_tracker.h:80
Object_lifetime_tracker(const Object_lifetime_tracker &other) noexcept
Copy-construct using the message "Copy-construct from ID".
Definition: object_lifetime_tracker.h:117
mrs::interface::RestHandler::HttpResult::Type Type
Definition: handler_content_file.cc:42
Definition: object_lifetime_tracker.h:37
std::string_view type_name()
Return the name of the given type (not demangled).
Definition: object_lifetime_tracker.h:57
int Tracker_id
Integral type used to uniquely identify objects.
Definition: object_lifetime_tracker.h:40
Tracker_id tracker_get_object_id()
The value to use for m_id next time we construct an Allocator.
Definition: object_lifetime_tracker.h:49
noexcept
The return type for any call_and_catch(f, args...) call where f(args...) returns Type.
Definition: call_and_catch.h:76
repeated Source source
Definition: replication_asynchronous_connection_failover.proto:42
case opt name
Definition: sslopt-case.h:29