// Returns callstack "formatted for debugging" - meaning that it // includes LR as the last item, and all items are the last step, // instead of "pointing ahead" bool GetCallstack(std::vector<CallstackEntry> &output) { if (!Core::IsRunning() || !PowerPC::HostIsRAMAddress(PowerPC::ppcState.gpr[1])) return false; if (LR == 0) { CallstackEntry entry; entry.Name = "(error: LR=0)"; entry.vAddress = 0x0; output.push_back(entry); return false; } CallstackEntry entry; entry.Name = StringFromFormat(" * %s [ LR = %08x ]\n", g_symbolDB.GetDescription(LR).c_str(), LR - 4); entry.vAddress = LR - 4; output.push_back(entry); WalkTheStack([&entry, &output](u32 func_addr) { std::string func_desc = g_symbolDB.GetDescription(func_addr); if (func_desc.empty() || func_desc == "Invalid") func_desc = "(unknown)"; entry.Name = StringFromFormat(" * %s [ addr = %08x ]\n", func_desc.c_str(), func_addr - 4); entry.vAddress = func_addr - 4; output.push_back(entry); }); return true; }
void PrintCallstack() { printf("== STACK TRACE - SP = %08x ==", PowerPC::ppcState.gpr[1]); if (LR == 0) { printf(" LR = 0 - this is bad"); } if (g_symbolDB.GetDescription(PC) != g_symbolDB.GetDescription(LR)) { printf(" * %s [ LR = %08x ]", g_symbolDB.GetDescription(LR).c_str(), LR); } WalkTheStack([](u32 func_addr) { std::string func_desc = g_symbolDB.GetDescription(func_addr); if (func_desc.empty() || func_desc == "Invalid") func_desc = "(unknown)"; printf(" * %s [ addr = %08x ]", func_desc.c_str(), func_addr); }); }
void PrintCallstack(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level) { GENERIC_LOG(type, level, "== STACK TRACE - SP = %08x ==", PowerPC::ppcState.gpr[1]); if (LR == 0) { GENERIC_LOG(type, level, " LR = 0 - this is bad"); } if (g_symbolDB.GetDescription(PC) != g_symbolDB.GetDescription(LR)) { GENERIC_LOG(type, level, " * %s [ LR = %08x ]", g_symbolDB.GetDescription(LR).c_str(), LR); } WalkTheStack([type, level](u32 func_addr) { std::string func_desc = g_symbolDB.GetDescription(func_addr); if (func_desc.empty() || func_desc == "Invalid") func_desc = "(unknown)"; GENERIC_LOG(type, level, " * %s [ addr = %08x ]", func_desc.c_str(), func_addr); }); }
void foo3(void) { puts("Entering foo3"); WalkTheStack(); puts("Ending foo2"); }