1/* 2 * Copyright 2012, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "CliStackTraceCommand.h" 8 9#include <stdio.h> 10 11#include <AutoLocker.h> 12 13#include "CliContext.h" 14#include "StackTrace.h" 15#include "Team.h" 16#include "UiUtils.h" 17 18 19CliStackTraceCommand::CliStackTraceCommand() 20 : 21 CliCommand("print a stack trace of the current thread", 22 "%s\n" 23 "Prints a stack trace for the current thread.") 24{ 25} 26 27 28void 29CliStackTraceCommand::Execute(int argc, const char* const* argv, 30 CliContext& context) 31{ 32 // get the current thread 33 Team* team = context.GetTeam(); 34 AutoLocker<Team> teamLocker(team); 35 Thread* thread = context.CurrentThread(); 36 if (thread == NULL) { 37 printf("no current thread\n"); 38 return; 39 } 40 41 if (thread->State() != THREAD_STATE_STOPPED) { 42 printf("Current thread is not stopped. Can't get stack trace.\n"); 43 return; 44 } 45 46 // get its stack trace 47 StackTrace* stackTrace = thread->GetStackTrace(); 48 while (stackTrace == NULL) { 49 context.WaitForEvent(CliContext::MSG_THREAD_STACK_TRACE_CHANGED); 50 if (context.IsTerminating()) 51 return; 52 stackTrace = thread->GetStackTrace(); 53 } 54 BReference<StackTrace> stackTraceReference(stackTrace); 55 // hold a reference until we're done 56 57 teamLocker.Unlock(); 58 59 // print the stack trace 60 int32 frameCount = stackTrace->CountFrames(); 61 for (int32 i = 0; i < frameCount; i++) { 62 StackFrame* frame = stackTrace->FrameAt(i); 63 printf("%3" B_PRId32 " %#" B_PRIx64 " %#" B_PRIx64, i, 64 (uint64)frame->FrameAddress(), (uint64)frame->InstructionPointer()); 65 66 char functionName[512]; 67 UiUtils::FunctionNameForFrame(frame, functionName, 68 sizeof(functionName)); 69 printf(" %s\n", functionName); 70 } 71} 72