Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ Unreleased:
* Added "Expand all" and "Collapse all" to the track menu to expand or
collapse a track group and all of its descendants.
SDK:
*
* Fixed MSVC hanging while compiling a scoped TRACE_EVENT used inside a
lambda when the legacy lambda processor is in use (C++17 without
/permissive-). See https://github.com/google/perfetto/issues/7591.
Misc:
* Added the `perfetto_cxx_standard` GN arg (default "c++17") to allow
standalone builds to use a newer C++ standard (e.g. "c++20").
Expand Down
18 changes: 18 additions & 0 deletions include/perfetto/tracing/internal/track_event_data_source.h
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,24 @@ class TrackEvent {
DecayArgType(args)...);
}

// Used by PERFETTO_INTERNAL_SCOPED_TRACK_EVENT_END.
static void TraceScopedEventEnd(size_t category_index)
PERFETTO_ALWAYS_INLINE {
CallIfCategoryEnabled(category_index, [category_index](uint32_t instances) {
TraceForCategory(instances, category_index, /*name=*/nullptr,
protos::pbzero::TrackEvent::TYPE_SLICE_END);
});
}

template <typename CategoryType>
static void TraceScopedEventEndForDynamicCategory(
const CategoryType& category) PERFETTO_ALWAYS_INLINE {
CallIfEnabled([&category](uint32_t instances) {
TraceForCategory(instances, category, /*name=*/nullptr,
protos::pbzero::TrackEvent::TYPE_SLICE_END);
});
}

// TraceState overloads
template <
typename CategoryType,
Expand Down
21 changes: 20 additions & 1 deletion include/perfetto/tracing/internal/track_event_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,25 @@
} \
} while (false)

// Like TRACE_EVENT_END(category), but without lambdas. A lambda in the scoped
// event finalizer's destructor makes MSVC hang when TRACE_EVENT is used inside
// a lambda (without /permissive-). See
// https://github.com/google/perfetto/issues/7591.
#define PERFETTO_INTERNAL_SCOPED_TRACK_EVENT_END(category) \
do { \
namespace tns = PERFETTO_TRACK_EVENT_NAMESPACE; \
PERFETTO_INTERNAL_STATIC_FOR_MSVC constexpr size_t PERFETTO_UID( \
kCatIndex_ADD_TO_PERFETTO_DEFINE_CATEGORIES_IF_FAILS_) = \
PERFETTO_GET_CATEGORY_INDEX(category); \
if (::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory( \
category)) { \
tns::TrackEvent::TraceScopedEventEndForDynamicCategory(category); \
} else { \
tns::TrackEvent::TraceScopedEventEnd(PERFETTO_UID( \
kCatIndex_ADD_TO_PERFETTO_DEFINE_CATEGORIES_IF_FAILS_)); \
} \
} while (false)

// C++17 doesn't like a move constructor being defined for the EventFinalizer
// class but C++11 and MSVC doesn't compile without it being defined so support
// both.
Expand All @@ -181,7 +200,7 @@
/* scope if used in a single line if statement. */ \
EventFinalizer(...) {} \
~EventFinalizer() { \
TRACE_EVENT_END(category); \
PERFETTO_INTERNAL_SCOPED_TRACK_EVENT_END(category); \
} \
\
EventFinalizer(const EventFinalizer&) = delete; \
Expand Down
23 changes: 23 additions & 0 deletions src/tracing/test/api_integrationtest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3852,6 +3852,29 @@ TEST_P(PerfettoApiTest, TrackEventScoped) {
"E", "B:test.TestEvent", "B:test.AnotherEvent", "E", "E"));
}

// Regression test for https://github.com/google/perfetto/issues/7591.
TEST_P(PerfettoApiTest, TrackEventScopedInsideLambda) {
auto* tracing_session = NewTraceWithCategories({"test"});
tracing_session->get()->StartBlocking();

auto simple = []() { TRACE_EVENT("test", "InLambda"); };
simple();

auto with_args = [](uint64_t arg) {
TRACE_EVENT("test", "InLambdaWithArgs", [&](perfetto::EventContext ctx) {
ctx.event()->set_log_message()->set_body_iid(arg);
});
};
with_args(123);

auto disabled = []() { TRACE_EVENT("foo", "DisabledEvent"); };
disabled();

auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
EXPECT_THAT(slices, ElementsAre("B:test.InLambda", "E",
"B:test.InLambdaWithArgs", "E"));
}

// A class similar to what Protozero generates for extended message.
class TestTrackEvent : public perfetto::protos::pbzero::TrackEvent {
public:
Expand Down
Loading