`PROF_MEMORY_TRACE` turned on in conjunction for sampling mode (see
below).
+ - `PROF_MEMORY_MIN_SIZE_LIMIT` - collect data about allocations for objects
+ with size more or equal `PROF_MEMORY_MIN_SIZE_LIMIT` amount of bytes.
+ Default value is `0` (limit is disabled).
+
+ - `PROF_MEMORY_MAX_SIZE_LIMIT` - collect data about allocations for objects
+ with size less or equal `PROF_MEMORY_MAX_SIZE_LIMIT` amount of bytes.
+ Must be greater or equal to `PROF_MEMORY_MIN_SIZE_LIMIT` or will be disabled.
+ Default value is `0` (limit is disabled).
+
+ - `PROF_STACK_DEPTH_LIMIT` - track changes of execution stack for first
+ `PROF_STACK_DEPTH_LIMIT` frames only. Default value is `0` (limit is disabled).
+ _Current limitation: `PROF_EXECUTION_TRACE` or `PROF_MEMORY_TRACE`
+ should also be enabled to use this options._
+
- `PROF_GC_TRACE` - enables tracking of GC events. Value of this options is
used as default for following options. However, each following
option can be turned on or off manually. `PROF_GC_TRACE` is defaulted to
FetchValue("PROF_HIGH_GRAN", new_config.HighGranularityEnabled);
FetchValue("PROF_DELAYED_START", new_config.TracingSuspendedOnStart);
FetchValue("PROF_LINE_TRACE", new_config.LineTraceEnabled);
+ FetchValue("PROF_STACK_DEPTH_LIMIT", new_config.StackDepthLimit);
bool CpuTraceEnabled;
if (FetchValue("PROF_CPU_TRACE", CpuTraceEnabled))
}
FetchValue("PROF_STACK_TRACK", new_config.StackTrackingEnabled);
+ FetchValue("PROF_MEMORY_MIN_SIZE_LIMIT", new_config.MemoryMinSizeLimit);
+ FetchValue("PROF_MEMORY_MAX_SIZE_LIMIT", new_config.MemoryMaxSizeLimit);
bool GcTraceEnabled;
if (FetchValue("PROF_GC_TRACE", GcTraceEnabled))
, HighGranularityEnabled(true)
, TracingSuspendedOnStart(false)
, LineTraceEnabled(false)
+ , StackDepthLimit(0)
, CpuTraceProcessEnabled(false)
, CpuTraceThreadEnabled(false)
, CpuTraceTimeoutMs(10)
, ExecutionTraceEnabled(false)
, MemoryTraceEnabled(false)
, StackTrackingEnabled(false)
+ , MemoryMinSizeLimit(0)
+ , MemoryMaxSizeLimit(0)
, GcGenerationBoundsTraceEnabled(false)
, GcAllocTableTraceEnabled(false)
{}
warnings.push_back(
"line tracing requires execution or memory tracing");
}
+
+ if (StackDepthLimit != 0)
+ {
+ warnings.push_back(
+ "stack trace depth limit requires execution or memory tracing");
+ }
}
if (!MemoryTraceEnabled)
warnings.push_back("stack tracking is memory tracing option");
}
+ if (MemoryMinSizeLimit != 0)
+ {
+ warnings.push_back("memory min size limit is memory tracing option");
+ }
+
+ if (MemoryMaxSizeLimit != 0)
+ {
+ warnings.push_back("memory max size limit is memory tracing option");
+ }
+
if (GcGenerationBoundsTraceEnabled)
{
warnings.push_back(
}
}
+ if (MemoryMaxSizeLimit && MemoryMinSizeLimit > MemoryMaxSizeLimit)
+ {
+ MemoryMaxSizeLimit = 0;
+ warnings.push_back("memory max size limit must be greater or equal to memory min size limit, memory max size limit disabled");
+ }
+
return warnings;
}
bool HighGranularityEnabled;
bool TracingSuspendedOnStart;
bool LineTraceEnabled;
+ unsigned long StackDepthLimit;
//
// CPU Trace features.
bool MemoryTraceEnabled;
bool StackTrackingEnabled;
+ unsigned long MemoryMinSizeLimit;
+ unsigned long MemoryMaxSizeLimit;
bool GcGenerationBoundsTraceEnabled;
bool GcAllocTableTraceEnabled;
_ASSERTE(this->id != 0);
const ProfilerInfo &info = profiler.GetProfilerInfo();
- hr = this->InitializeTypeFromClassId(profiler, storage, classId);
+ hr = this->InitializeSize(profiler, info);
if (FAILED(hr) && SUCCEEDED(hrReturn))
{
hrReturn = hr;
}
- hr = this->InitializeSize(profiler, info);
+ if (this->size < profiler.GetConfig().MemoryMinSizeLimit ||
+ (profiler.GetConfig().MemoryMaxSizeLimit && this->size > profiler.GetConfig().MemoryMaxSizeLimit))
+ {
+ return hrReturn;
+ }
+
+ hr = this->InitializeTypeFromClassId(profiler, storage, classId);
if (FAILED(hr) && SUCCEEDED(hrReturn))
{
hrReturn = hr;
const Profiler &profiler,
const ProfilerInfo &info) noexcept;
-public:
HRESULT Initialize(
const Profiler &profiler,
ClassStorage &storage) noexcept;
+public:
HRESULT Initialize(
const Profiler &profiler,
ClassStorage &storage,
#include "traceinlines.h"
+// Related to PROF_STACK_DEPTH_LIMIT.
+thread_local unsigned long SkippedTopFramesCount = 0;
+
EXTERN_C UINT_PTR __stdcall FunctionIDMapStub(
FunctionID funcId,
void *clientData,
void ExecutionTrace::UpdateCallStackPush(const FunctionInfo &funcInfo) noexcept
{
+ if (m_profiler.GetConfig().StackDepthLimit && // In case `StackDepthLimit` == 0 limit is disabled.
+ m_profiler.GetCommonTrace().GetThreadInfo()->eventChannel.GetStackSize() > m_profiler.GetConfig().StackDepthLimit)
+ {
+ SkippedTopFramesCount++;
+ return;
+ }
+
SamplingSharedState state = {};
state.stackWillBeChanged = true;
m_profiler.GetCommonTrace().InterruptSampling(
void ExecutionTrace::UpdateCallStackPush(
const FunctionInfo &funcInfo, UINT_PTR prevIP) noexcept
{
+ if (m_profiler.GetConfig().StackDepthLimit && // In case `StackDepthLimit` == 0 limit is disabled.
+ m_profiler.GetCommonTrace().GetThreadInfo()->eventChannel.GetStackSize() > m_profiler.GetConfig().StackDepthLimit)
+ {
+ SkippedTopFramesCount++;
+ return;
+ }
+
SamplingSharedState state = {};
state.stackWillBeChanged = true;
m_profiler.GetCommonTrace().InterruptSampling(
void ExecutionTrace::UpdateCallStackPop() noexcept
{
+ if (SkippedTopFramesCount)
+ {
+ SkippedTopFramesCount--;
+ return;
+ }
+
SamplingSharedState state = {};
state.stackWillBeChanged = true;
bool needPrintWarning = false;
);
}
+ if (objInfo.size < m_profiler.GetConfig().MemoryMinSizeLimit ||
+ (m_profiler.GetConfig().MemoryMaxSizeLimit && objInfo.size > m_profiler.GetConfig().MemoryMaxSizeLimit))
+ {
+ continue;
+ }
+
_ASSERTE(objInfo.type != nullptr);
if (objInfo.type->needPrintLoadFinished)
{
);
}
+ if (objInfo.size < m_profiler.GetConfig().MemoryMinSizeLimit ||
+ (m_profiler.GetConfig().MemoryMaxSizeLimit && objInfo.size > m_profiler.GetConfig().MemoryMaxSizeLimit))
+ {
+ return hr;
+ }
+
_ASSERTE(objInfo.type != nullptr);
if (objInfo.type->needPrintLoadFinished)
{
m_tracefmt.log("prf cfg", g_tls_ss).str("HighGranularityEnabled").config(config.HighGranularityEnabled).end();
m_tracefmt.log("prf cfg", g_tls_ss).str("TracingSuspendedOnStart").config(config.TracingSuspendedOnStart).end();
m_tracefmt.log("prf cfg", g_tls_ss).str("LineTraceEnabled").config(config.LineTraceEnabled).end();
+ m_tracefmt.log("prf cfg", g_tls_ss).str("StackDepthLimit").config(config.StackDepthLimit).end();
m_tracefmt.log("prf cfg", g_tls_ss).str("CpuTraceProcessEnabled").config(config.CpuTraceProcessEnabled).end();
m_tracefmt.log("prf cfg", g_tls_ss).str("CpuTraceThreadEnabled").config(config.CpuTraceThreadEnabled).end();
m_tracefmt.log("prf cfg", g_tls_ss).str("CpuTraceTimeoutMs").config(config.CpuTraceTimeoutMs).end();
m_tracefmt.log("prf cfg", g_tls_ss).str("ExecutionTraceEnabled").config(config.ExecutionTraceEnabled).end();
m_tracefmt.log("prf cfg", g_tls_ss).str("MemoryTraceEnabled").config(config.MemoryTraceEnabled).end();
m_tracefmt.log("prf cfg", g_tls_ss).str("StackTrackingEnabled").config(config.StackTrackingEnabled).end();
+ m_tracefmt.log("prf cfg", g_tls_ss).str("MemoryMinSizeLimit").config(config.MemoryMinSizeLimit).end();
+ m_tracefmt.log("prf cfg", g_tls_ss).str("MemoryMaxSizeLimit").config(config.MemoryMaxSizeLimit).end();
m_tracefmt.log("prf cfg", g_tls_ss).str("GcAllocTableTraceEnabled").config(config.GcAllocTableTraceEnabled).end();
AddTLSDataToQueue();
}