void CliStackTraceCommand::Execute(int argc, const char* const* argv, CliContext& context) { // get the current thread Team* team = context.GetTeam(); AutoLocker<Team> teamLocker(team); Thread* thread = context.CurrentThread(); if (thread == NULL) { printf("no current thread\n"); return; } if (thread->State() != THREAD_STATE_STOPPED) { printf("Current thread is not stopped. Can't get stack trace.\n"); return; } // get its stack trace StackTrace* stackTrace = thread->GetStackTrace(); while (stackTrace == NULL) { context.WaitForEvents(CliContext::EVENT_THREAD_STACK_TRACE_CHANGED); if (context.IsTerminating()) return; stackTrace = thread->GetStackTrace(); } BReference<StackTrace> stackTraceReference(stackTrace); // hold a reference until we're done teamLocker.Unlock(); // print the stack trace int32 frameCount = stackTrace->CountFrames(); for (int32 i = 0; i < frameCount; i++) { StackFrame* frame = stackTrace->FrameAt(i); printf("%3" B_PRId32 " %#" B_PRIx64 " %#" B_PRIx64, i, (uint64)frame->FrameAddress(), (uint64)frame->InstructionPointer()); char functionName[512]; UiUtils::FunctionNameForFrame(frame, functionName, sizeof(functionName)); printf(" %s\n", functionName); } }
void CliContext::ProcessPendingEvents() { AutoLocker<Team> teamLocker(fTeam); for (;;) { // get the next event AutoLocker<BLocker> locker(fLock); Event* event = fPendingEvents.RemoveHead(); locker.Unlock(); if (event == NULL) break; ObjectDeleter<Event> eventDeleter(event); // process the event Thread* thread = event->GetThread(); switch (event->Type()) { case EVENT_QUIT: case EVENT_DEBUG_REPORT_CHANGED: case EVENT_USER_INTERRUPT: break; case EVENT_THREAD_ADDED: printf("[new thread: %" B_PRId32 " \"%s\"]\n", thread->ID(), thread->Name()); break; case EVENT_THREAD_REMOVED: printf("[thread terminated: %" B_PRId32 " \"%s\"]\n", thread->ID(), thread->Name()); break; case EVENT_THREAD_STOPPED: printf("[thread stopped: %" B_PRId32 " \"%s\"]\n", thread->ID(), thread->Name()); break; case EVENT_THREAD_STACK_TRACE_CHANGED: if (thread == fCurrentThread) { fCurrentStackTrace = thread->GetStackTrace(); fCurrentStackTrace->AcquireReference(); SetCurrentStackFrameIndex(0); } break; case EVENT_TEAM_MEMORY_BLOCK_RETRIEVED: if (fCurrentBlock != NULL) { fCurrentBlock->ReleaseReference(); fCurrentBlock = NULL; } fCurrentBlock = event->GetMemoryBlock(); break; case EVENT_EXPRESSION_EVALUATED: fExpressionResult = event->GetExpressionResult(); if (fExpressionValue != NULL) { fExpressionValue->ReleaseReference(); fExpressionValue = NULL; } fExpressionValue = event->GetExpressionValue(); if (fExpressionValue != NULL) fExpressionValue->AcquireReference(); break; } } }