tracing_stack_trace* capture_tracing_stack_trace(int32 maxCount, int32 skipFrames, bool kernelOnly) { #if ENABLE_TRACING // page_fault_exception() doesn't allow us to gracefully handle a bad // address in the stack trace, if interrupts are disabled, so we always // restrict the stack traces to the kernel only in this case. A bad address // in the kernel stack trace would still cause a panic(), but this is // probably even desired. if (!are_interrupts_enabled()) kernelOnly = true; tracing_stack_trace* stackTrace = (tracing_stack_trace*)alloc_tracing_buffer( sizeof(tracing_stack_trace) + maxCount * sizeof(addr_t)); if (stackTrace != NULL) { stackTrace->depth = arch_debug_get_stack_trace( stackTrace->return_addresses, maxCount, 0, skipFrames + 1, STACK_TRACE_KERNEL | (kernelOnly ? 0 : STACK_TRACE_USER)); } return stackTrace; #else return NULL; #endif }
void SystemProfiler::_DoSample() { Thread* thread = thread_get_current_thread(); int cpu = thread->cpu->cpu_num; 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); InterruptsSpinLocker locker(fLock); system_profiler_samples* event = (system_profiler_samples*) _AllocateBuffer(sizeof(system_profiler_samples) + count * sizeof(addr_t), B_SYSTEM_PROFILER_SAMPLES, cpu, count); if (event == NULL) return; event->thread = thread->id; memcpy(event->samples, cpuData.buffer, count * sizeof(addr_t)); fHeader->size = fBufferSize; }