aboutsummaryrefslogtreecommitdiff
path: root/include/perfetto/tracing/track_event.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/perfetto/tracing/track_event.h')
-rw-r--r--include/perfetto/tracing/track_event.h194
1 files changed, 63 insertions, 131 deletions
diff --git a/include/perfetto/tracing/track_event.h b/include/perfetto/tracing/track_event.h
index 7e226f0d1..8eebf76ba 100644
--- a/include/perfetto/tracing/track_event.h
+++ b/include/perfetto/tracing/track_event.h
@@ -21,7 +21,6 @@
#include "perfetto/tracing/internal/track_event_data_source.h"
#include "perfetto/tracing/internal/track_event_internal.h"
#include "perfetto/tracing/internal/track_event_macros.h"
-#include "perfetto/tracing/string_helpers.h"
#include "perfetto/tracing/track.h"
#include "perfetto/tracing/track_event_category_registry.h"
#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
@@ -152,6 +151,32 @@ constexpr bool IsDynamicCategory(const ::perfetto::DynamicCategory&) {
} // namespace internal
} // namespace PERFETTO_TRACK_EVENT_NAMESPACE
+namespace perfetto {
+
+// A wrapper for marking strings that can't be determined to be static at build
+// time, but are in fact static.
+class PERFETTO_EXPORT StaticString final {
+ public:
+ const char* value;
+
+ operator const char*() const { return value; }
+};
+
+namespace internal {
+
+template <typename T = void>
+constexpr bool IsStaticString(const char*) {
+ return true;
+}
+
+template <typename T = void>
+constexpr bool IsStaticString(...) {
+ return false;
+}
+
+} // namespace internal
+} // namespace perfetto
+
// Normally all categories are defined statically at build-time (see
// PERFETTO_DEFINE_CATEGORIES). However, some categories are only used for
// testing, and we shouldn't publish them to the tracing service or include them
@@ -193,9 +218,36 @@ constexpr bool IsDynamicCategory(const ::perfetto::DynamicCategory&) {
perfetto::internal::TrackEventDataSourceTraits)
// Ignore GCC warning about a missing argument for a variadic macro parameter.
-#if defined(__GNUC__) || defined(__clang__)
#pragma GCC system_header
-#endif
+
+// Ensure that |string| is a static constant string.
+//
+// If you get a compiler failure here, you are most likely trying to use
+// TRACE_EVENT with a dynamic event name. There are two ways to fix this:
+//
+// 1) If the event name is actually dynamic (e.g., std::string), write it into
+// the event manually:
+//
+// TRACE_EVENT("category", nullptr, [&](perfetto::EventContext ctx) {
+// ctx.event()->set_name(dynamic_name);
+// });
+//
+// 2) If the name is static, but the pointer is computed at runtime, wrap it
+// with perfetto::StaticString:
+//
+// TRACE_EVENT("category", perfetto::StaticString{name});
+//
+// DANGER: Using perfetto::StaticString with strings whose contents change
+// dynamically can cause silent trace data corruption.
+//
+#define PERFETTO_GET_STATIC_STRING(string) \
+ [&]() { \
+ static_assert( \
+ std::is_same<decltype(string), ::perfetto::StaticString>::value || \
+ ::perfetto::internal::IsStaticString(string), \
+ "String must be static"); \
+ return static_cast<const char*>(string); \
+ }()
// Begin a slice under |category| with the title |name|. Both strings must be
// static constants. The track event is only recorded if |category| is enabled
@@ -212,93 +264,15 @@ constexpr bool IsDynamicCategory(const ::perfetto::DynamicCategory&) {
// ctx.event()->set_name(dynamic_name);
// });
//
-// The following optional arguments can be passed to `TRACE_EVENT` to add extra
-// information to events:
-//
-// TRACE_EVENT("cat", "name"[, track][, timestamp]
-// [, "debug_name1", debug_value1]
-// [, "debug_name2", debug_value2]
-// ...
-// [, "debug_nameN", debug_valueN]
-// [, lambda]);
-//
-// Some examples of valid combinations:
-//
-// 1. A lambda for writing custom TrackEvent fields:
-//
-// TRACE_EVENT("category", "Name", [&](perfetto::EventContext ctx) {
-// ctx.event()->set_custom_value(...);
-// });
-//
-// 2. A timestamp and a lambda:
-//
-// TRACE_EVENT("category", "Name", time_in_nanoseconds,
-// [&](perfetto::EventContext ctx) {
-// ctx.event()->set_custom_value(...);
-// });
-//
-// |time_in_nanoseconds| should be an uint64_t by default. To support custom
-// timestamp types,
-// |perfetto::TraceTimestampTraits<T>::ConvertTimestampToTraceTimeNs|
-// should be defined. See |ConvertTimestampToTraceTimeNs| for more details.
-//
-// 3. Arbitrary number of debug annotations:
-//
-// TRACE_EVENT("category", "Name", "arg", value);
-// TRACE_EVENT("category", "Name", "arg", value, "arg2", value2);
-// TRACE_EVENT("category", "Name", "arg", value, "arg2", value2,
-// "arg3", value3);
-//
-// See |TracedValue| for recording custom types as debug annotations.
-//
-// 4. Arbitrary number of debug annotations and a lambda:
-//
-// TRACE_EVENT("category", "Name", "arg", value,
-// [&](perfetto::EventContext ctx) {
-// ctx.event()->set_custom_value(...);
-// });
-//
-// 5. An overridden track:
-//
-// TRACE_EVENT("category", "Name", perfetto::Track(1234));
-//
-// See |Track| for other types of tracks which may be used.
-//
-// 6. A track and a lambda:
-//
-// TRACE_EVENT("category", "Name", perfetto::Track(1234),
-// [&](perfetto::EventContext ctx) {
-// ctx.event()->set_custom_value(...);
-// });
-//
-// 7. A track and a timestamp:
-//
-// TRACE_EVENT("category", "Name", perfetto::Track(1234),
-// time_in_nanoseconds);
-//
-// 8. A track, a timestamp and a lambda:
-//
-// TRACE_EVENT("category", "Name", perfetto::Track(1234),
-// time_in_nanoseconds, [&](perfetto::EventContext ctx) {
-// ctx.event()->set_custom_value(...);
-// });
-//
-// 9. A track and an arbitrary number of debug annotions:
-//
-// TRACE_EVENT("category", "Name", perfetto::Track(1234),
-// "arg", value);
-// TRACE_EVENT("category", "Name", perfetto::Track(1234),
-// "arg", value, "arg2", value2);
-//
-#define TRACE_EVENT_BEGIN(category, name, ...) \
- PERFETTO_INTERNAL_TRACK_EVENT( \
- category, ::perfetto::internal::GetStaticString(name), \
+#define TRACE_EVENT_BEGIN(category, name, ...) \
+ PERFETTO_INTERNAL_TRACK_EVENT( \
+ category, PERFETTO_GET_STATIC_STRING(name), \
::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN, ##__VA_ARGS__)
// End a slice under |category|.
#define TRACE_EVENT_END(category, ...) \
PERFETTO_INTERNAL_TRACK_EVENT( \
- category, /*name=*/nullptr, \
+ category, nullptr, \
::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END, ##__VA_ARGS__)
// Begin a slice which gets automatically closed when going out of scope.
@@ -306,9 +280,9 @@ constexpr bool IsDynamicCategory(const ::perfetto::DynamicCategory&) {
PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(category, name, ##__VA_ARGS__)
// Emit a slice which has zero duration.
-#define TRACE_EVENT_INSTANT(category, name, ...) \
- PERFETTO_INTERNAL_TRACK_EVENT( \
- category, ::perfetto::internal::GetStaticString(name), \
+#define TRACE_EVENT_INSTANT(category, name, ...) \
+ PERFETTO_INTERNAL_TRACK_EVENT( \
+ category, PERFETTO_GET_STATIC_STRING(name), \
::perfetto::protos::pbzero::TrackEvent::TYPE_INSTANT, ##__VA_ARGS__)
// Efficiently determine if the given static or dynamic trace category or
@@ -316,49 +290,7 @@ constexpr bool IsDynamicCategory(const ::perfetto::DynamicCategory&) {
#define TRACE_EVENT_CATEGORY_ENABLED(category) \
PERFETTO_INTERNAL_CATEGORY_ENABLED(category)
-// Time-varying numeric data can be recorded with the TRACE_COUNTER macro:
-//
-// TRACE_COUNTER("cat", counter_track[, timestamp], value);
-//
-// For example, to record a single value for a counter called "MyCounter":
-//
-// TRACE_COUNTER("category", "MyCounter", 1234.5);
-//
-// This data is displayed as a counter track in the Perfetto UI.
-//
-// Both integer and floating point counter values are supported. Counters can
-// also be annotated with additional information such as units, for example, for
-// tracking the rendering framerate in terms of frames per second or "fps":
-//
-// TRACE_COUNTER("category", perfetto::CounterTrack("Framerate", "fps"), 120);
-//
-// As another example, a memory counter that records bytes but accepts samples
-// as kilobytes (to reduce trace binary size) can be defined like this:
-//
-// perfetto::CounterTrack memory_track = perfetto::CounterTrack("Memory")
-// .set_unit("bytes")
-// .set_multiplier(1024);
-// TRACE_COUNTER("category", memory_track, 4 /* = 4096 bytes */);
-//
-// See /protos/perfetto/trace/track_event/counter_descriptor.proto
-// for the full set of attributes for a counter track.
-//
-// To record a counter value at a specific point in time (instead of the current
-// time), you can pass in a custom timestamp:
-//
-// // First record the current time and counter value.
-// uint64_t timestamp = perfetto::TrackEvent::GetTraceTimeNs();
-// int64_t value = 1234;
-//
-// // Later, emit a sample at that point in time.
-// TRACE_COUNTER("category", "MyCounter", timestamp, value);
-//
-#define TRACE_COUNTER(category, track, ...) \
- PERFETTO_INTERNAL_TRACK_EVENT( \
- category, /*name=*/nullptr, \
- ::perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER, \
- ::perfetto::CounterTrack(track), ##__VA_ARGS__)
-
// TODO(skyostil): Add flow events.
+// TODO(skyostil): Add counters.
#endif // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_H_