profiler: Actually support profiling user stack frames only.
The "-k" argument (which never did anything before) is now inverted compared to what it used to be, i.e. now specifying it will profile kernel frames, too, whereas by default only user frames will be sampled.
This commit is contained in:
@@ -407,6 +407,7 @@ typedef struct {
|
||||
bool variable_stack_depth;
|
||||
// variable number of samples per hit;
|
||||
// cf. debug_profiler_update
|
||||
bool profile_kernel; // sample kernel stack frames
|
||||
} debug_nub_start_profiler;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -147,6 +147,8 @@ struct thread_debug_info {
|
||||
// the buffer
|
||||
bool variable_stack_depth;
|
||||
// record a variable number of samples per hit
|
||||
bool profile_kernel;
|
||||
// record samples in kernel stack frames
|
||||
bool buffer_full;
|
||||
// indicates that the sample buffer is full
|
||||
union {
|
||||
|
||||
@@ -21,6 +21,7 @@ struct system_profiler_parameters {
|
||||
// sampling
|
||||
bigtime_t interval; // interval at which to take samples
|
||||
uint32 stack_depth; // maximum stack depth to sample
|
||||
bool profile_kernel; // sample kernel stack frames
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ struct Options {
|
||||
output(NULL),
|
||||
callgrind_directory(NULL),
|
||||
profile_all(false),
|
||||
profile_kernel(true),
|
||||
profile_kernel(false),
|
||||
profile_loading(false),
|
||||
profile_teams(true),
|
||||
profile_threads(true),
|
||||
|
||||
@@ -157,6 +157,7 @@ Team::InitThread(Thread* thread)
|
||||
message.sample_area = sampleArea;
|
||||
message.stack_depth = gOptions.stack_depth;
|
||||
message.variable_stack_depth = gOptions.analyze_full_stack;
|
||||
message.profile_kernel = gOptions.profile_kernel;
|
||||
|
||||
debug_nub_start_profiler_reply reply;
|
||||
error = send_debug_message(&fDebugContext,
|
||||
|
||||
@@ -79,7 +79,7 @@ static const char* kUsage =
|
||||
" Default is 1000 (1 ms). On a fast machine, a shorter\n"
|
||||
" interval might lead to better results, while it might\n"
|
||||
" make them worse on slow machines.\n"
|
||||
" -k - Don't check kernel images for hits.\n"
|
||||
" -k - Also profile kernel frames.\n"
|
||||
" -l - Also profile loading the executable.\n"
|
||||
" -o <output> - Print the results to file <output>.\n"
|
||||
" -r, --recorded - Don't profile, but evaluate a recorded kernel profile\n"
|
||||
@@ -712,6 +712,7 @@ profile_all(const char* const* programArgs, int programArgCount)
|
||||
| B_SYSTEM_PROFILER_SAMPLING_EVENTS;
|
||||
profilerParameters.interval = gOptions.interval;
|
||||
profilerParameters.stack_depth = gOptions.stack_depth;
|
||||
profilerParameters.profile_kernel = gOptions.profile_kernel;
|
||||
|
||||
error = _kern_system_profiler_start(&profilerParameters);
|
||||
if (error != B_OK) {
|
||||
@@ -1055,7 +1056,7 @@ main(int argc, const char* const* argv)
|
||||
gOptions.interval = atol(optarg);
|
||||
break;
|
||||
case 'k':
|
||||
gOptions.profile_kernel = false;
|
||||
gOptions.profile_kernel = true;
|
||||
break;
|
||||
case 'l':
|
||||
gOptions.profile_loading = true;
|
||||
|
||||
@@ -180,6 +180,7 @@ private:
|
||||
uint32 fFlags;
|
||||
uint32 fStackDepth;
|
||||
bigtime_t fInterval;
|
||||
bool fProfileKernel;
|
||||
system_profiler_buffer_header* fHeader;
|
||||
uint8* fBufferBase;
|
||||
size_t fBufferCapacity;
|
||||
@@ -257,6 +258,7 @@ SystemProfiler::SystemProfiler(team_id team, const area_info& userAreaInfo,
|
||||
fFlags(parameters.flags),
|
||||
fStackDepth(parameters.stack_depth),
|
||||
fInterval(parameters.interval),
|
||||
fProfileKernel(parameters.profile_kernel),
|
||||
fHeader(NULL),
|
||||
fBufferBase(NULL),
|
||||
fBufferCapacity(0),
|
||||
@@ -1413,8 +1415,14 @@ SystemProfiler::_DoSample()
|
||||
CPUProfileData& cpuData = fCPUData[cpu];
|
||||
|
||||
// get the samples
|
||||
int32 count = arch_debug_get_stack_trace(cpuData.buffer, fStackDepth, 1,
|
||||
0, STACK_TRACE_KERNEL | STACK_TRACE_USER);
|
||||
uint32 flags = STACK_TRACE_USER;
|
||||
int32 skipIFrames = 0;
|
||||
if (fProfileKernel) {
|
||||
flags |= STACK_TRACE_KERNEL;
|
||||
skipIFrames = 1;
|
||||
}
|
||||
int32 count = arch_debug_get_stack_trace(cpuData.buffer, fStackDepth,
|
||||
skipIFrames, 0, flags);
|
||||
|
||||
InterruptsSpinLocker locker(fLock);
|
||||
|
||||
|
||||
@@ -1367,19 +1367,26 @@ profiling_do_sample(bool& flushBuffer)
|
||||
}
|
||||
|
||||
// get the samples
|
||||
uint32 flags = STACK_TRACE_USER;
|
||||
int32 skipIFrames = 0;
|
||||
if (debugInfo.profile.profile_kernel) {
|
||||
flags |= STACK_TRACE_KERNEL;
|
||||
skipIFrames = 1;
|
||||
}
|
||||
|
||||
addr_t* returnAddresses = debugInfo.profile.samples
|
||||
+ debugInfo.profile.sample_count;
|
||||
if (debugInfo.profile.variable_stack_depth) {
|
||||
// variable sample count per hit
|
||||
*returnAddresses = arch_debug_get_stack_trace(returnAddresses + 1,
|
||||
stackDepth - 1, 1, 0, STACK_TRACE_KERNEL | STACK_TRACE_USER);
|
||||
stackDepth - 1, skipIFrames, 0, flags);
|
||||
|
||||
debugInfo.profile.sample_count += *returnAddresses + 1;
|
||||
} else {
|
||||
// fixed sample count per hit
|
||||
if (stackDepth > 1) {
|
||||
if (stackDepth > 1 || !debugInfo.profile.profile_kernel) {
|
||||
int32 count = arch_debug_get_stack_trace(returnAddresses,
|
||||
stackDepth, 1, 0, STACK_TRACE_KERNEL | STACK_TRACE_USER);
|
||||
stackDepth, skipIFrames, 0, flags);
|
||||
|
||||
for (int32 i = count; i < stackDepth; i++)
|
||||
returnAddresses[i] = 0;
|
||||
@@ -2262,6 +2269,7 @@ debug_nub_thread(void *)
|
||||
int32 stackDepth = message.start_profiler.stack_depth;
|
||||
bool variableStackDepth
|
||||
= message.start_profiler.variable_stack_depth;
|
||||
bool profileKernel = message.start_profiler.profile_kernel;
|
||||
bigtime_t interval = max_c(message.start_profiler.interval,
|
||||
B_DEBUG_MIN_PROFILE_INTERVAL);
|
||||
status_t result = B_OK;
|
||||
@@ -2333,6 +2341,7 @@ debug_nub_thread(void *)
|
||||
threadDebugInfo.profile.stack_depth = stackDepth;
|
||||
threadDebugInfo.profile.variable_stack_depth
|
||||
= variableStackDepth;
|
||||
threadDebugInfo.profile.profile_kernel = profileKernel;
|
||||
threadDebugInfo.profile.buffer_full = false;
|
||||
threadDebugInfo.profile.interval_left = interval;
|
||||
threadDebugInfo.profile.installed_timer = NULL;
|
||||
|
||||
Reference in New Issue
Block a user