This is an optional mechanism that automatically detects roots. It's a best-effort mechanism, and its main goal is to *avoid* pointing at the message pump function as a root. This is the function that polls message queue(s) in an infinite loop, and is thus a bad root (it never exits). High-level, when collection is requested - which should happen when a server has already been set up and handing requests - we spend a bit of time sampling all the server's threads. Each sample is a stack which we insert in a `PerThreadCallsiteTrie`. After a while, we run for each `PerThreadCallsiteTrie` the root detection logic. We then traverse all the `FunctionData`, find the ones matching the detected roots, and allocate a `ContextRoot` for them. From here, we special case `FunctionData` objects, in `__llvm_ctx_profile_get_context, that have a `CtxRoot` and route them to `__llvm_ctx_profile_start_context`. For this to work, on the llvm side, we need to have all functions call `__llvm_ctx_profile_release_context` because they _might_ be roots. This comes at a slight (percentages) penalty during collection - which we can afford since the overall technique is ~5x faster than normal instrumentation. We can later explore conditionally enabling autoroot detection and avoiding this penalty, if desired. Note that functions that `musttail call` can't have their return instrumented this way, and a subsequent patch will harden the mechanism against this case. The mechanism could be used in combination with explicit root specification, too.
35 lines
914 B
CMake
35 lines
914 B
CMake
add_compiler_rt_component(ctx_profile)
|
|
|
|
set(CTX_PROFILE_SOURCES
|
|
CtxInstrProfiling.cpp
|
|
RootAutoDetector.cpp
|
|
)
|
|
|
|
set(CTX_PROFILE_HEADERS
|
|
CtxInstrContextNode.h
|
|
CtxInstrProfiling.h
|
|
RootAutoDetector.h
|
|
)
|
|
|
|
include_directories(..)
|
|
include_directories(../../include)
|
|
|
|
# We don't use the C++ Standard Library here, so avoid including it by mistake.
|
|
append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ EXTRA_FLAGS)
|
|
|
|
# __sanitizer_siginfo
|
|
append_list_if(COMPILER_RT_HAS_WGNU_ANONYMOUS_STRUCT_FLAG -Wno-gnu-anonymous-struct EXTRA_FLAGS)
|
|
|
|
if(COMPILER_RT_INCLUDE_TESTS)
|
|
add_subdirectory(tests)
|
|
endif()
|
|
|
|
add_compiler_rt_runtime(clang_rt.ctx_profile
|
|
STATIC
|
|
ARCHS ${CTX_PROFILE_SUPPORTED_ARCH}
|
|
OBJECT_LIBS RTSanitizerCommon RTSanitizerCommonLibc RTSanitizerCommonSymbolizer
|
|
CFLAGS ${EXTRA_FLAGS}
|
|
SOURCES ${CTX_PROFILE_SOURCES}
|
|
ADDITIONAL_HEADERS ${CTX_PROFILE_HEADERS}
|
|
PARENT_TARGET ctx_profile)
|