#include "CliStackTraceCommand.h"
#include <stdio.h>
#include <AutoLocker.h>
#include "CliContext.h"
#include "StackTrace.h"
#include "Team.h"
#include "UiUtils.h"
CliStackTraceCommand::CliStackTraceCommand()
:
CliCommand("print a stack trace of the current thread",
"%s\n"
"Prints a stack trace for the current thread.")
{
}
void
CliStackTraceCommand::Execute(int argc, const char* const* argv,
CliContext& context)
{
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;
}
StackTrace* stackTrace = thread->GetStackTrace();
while (stackTrace == NULL) {
context.WaitForEvent(CliContext::MSG_THREAD_STACK_TRACE_CHANGED);
if (context.IsTerminating())
return;
stackTrace = thread->GetStackTrace();
}
BReference<StackTrace> stackTraceReference(stackTrace);
teamLocker.Unlock();
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);
}
}