mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
Stack overflow detection
Added a gap between stack allocations PPU callstack improved
This commit is contained in:
parent
7ab210432e
commit
b349100d9d
@ -272,13 +272,17 @@ void ppu_thread::on_init(const std::shared_ptr<void>& _this)
|
||||
{
|
||||
if (!stack_addr)
|
||||
{
|
||||
const_cast<u32&>(stack_addr) = vm::alloc(stack_size, vm::stack);
|
||||
// Allocate stack + gap between stacks
|
||||
const_cast<u32&>(stack_addr) = vm::alloc(stack_size + 4096, vm::stack) + 4096;
|
||||
|
||||
if (!stack_addr)
|
||||
{
|
||||
fmt::throw_exception("Out of stack memory (size=0x%x)" HERE, stack_size);
|
||||
}
|
||||
|
||||
// Make the gap inaccessible
|
||||
vm::page_protect(stack_addr - 4096, 4096, 0, 0, vm::page_readable + vm::page_writable);
|
||||
|
||||
gpr[1] = ::align(stack_addr + stack_size, 0x200) - 0x200;
|
||||
|
||||
cpu_thread::on_init(_this);
|
||||
@ -325,10 +329,10 @@ std::string ppu_thread::get_name() const
|
||||
std::string ppu_thread::dump() const
|
||||
{
|
||||
std::string ret = cpu_thread::dump();
|
||||
ret += fmt::format("Priority: %d\n", +prio);
|
||||
ret += fmt::format("Stack: 0x%x..0x%x\n", stack_addr, stack_addr + stack_size - 1);
|
||||
ret += fmt::format("Joiner: %s\n", join_status(joiner.load()));
|
||||
ret += fmt::format("Commands: %u\n", cmd_queue.size());
|
||||
fmt::append(ret, "Priority: %d\n", +prio);
|
||||
fmt::append(ret, "Stack: 0x%x..0x%x\n", stack_addr, stack_addr + stack_size - 1);
|
||||
fmt::append(ret, "Joiner: %s\n", join_status(joiner.load()));
|
||||
fmt::append(ret, "Commands: %u\n", cmd_queue.size());
|
||||
|
||||
const auto _func = last_function;
|
||||
|
||||
@ -341,7 +345,7 @@ std::string ppu_thread::dump() const
|
||||
|
||||
if (const auto _time = start_time)
|
||||
{
|
||||
ret += fmt::format("Waiting: %fs\n", (get_system_time() - _time) / 1000000.);
|
||||
fmt::append(ret, "Waiting: %fs\n", (get_system_time() - _time) / 1000000.);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -354,26 +358,38 @@ std::string ppu_thread::dump() const
|
||||
}
|
||||
|
||||
ret += "\nRegisters:\n=========\n";
|
||||
for (uint i = 0; i < 32; ++i) ret += fmt::format("GPR[%d] = 0x%llx\n", i, gpr[i]);
|
||||
for (uint i = 0; i < 32; ++i) ret += fmt::format("FPR[%d] = %.6G\n", i, fpr[i]);
|
||||
for (uint i = 0; i < 32; ++i) ret += fmt::format("VR[%d] = %s [x: %g y: %g z: %g w: %g]\n", i, vr[i], vr[i]._f[3], vr[i]._f[2], vr[i]._f[1], vr[i]._f[0]);
|
||||
for (uint i = 0; i < 32; ++i) fmt::append(ret, "GPR[%d] = 0x%llx\n", i, gpr[i]);
|
||||
for (uint i = 0; i < 32; ++i) fmt::append(ret, "FPR[%d] = %.6G\n", i, fpr[i]);
|
||||
for (uint i = 0; i < 32; ++i) fmt::append(ret, "VR[%d] = %s [x: %g y: %g z: %g w: %g]\n", i, vr[i], vr[i]._f[3], vr[i]._f[2], vr[i]._f[1], vr[i]._f[0]);
|
||||
|
||||
ret += fmt::format("CR = 0x%08x\n", cr_pack());
|
||||
ret += fmt::format("LR = 0x%llx\n", lr);
|
||||
ret += fmt::format("CTR = 0x%llx\n", ctr);
|
||||
ret += fmt::format("VRSAVE = 0x%08x\n", vrsave);
|
||||
ret += fmt::format("XER = [CA=%u | OV=%u | SO=%u | CNT=%u]\n", xer.ca, xer.ov, xer.so, xer.cnt);
|
||||
ret += fmt::format("VSCR = [SAT=%u | NJ=%u]\n", sat, nj);
|
||||
ret += fmt::format("FPSCR = [FL=%u | FG=%u | FE=%u | FU=%u]\n", fpscr.fl, fpscr.fg, fpscr.fe, fpscr.fu);
|
||||
fmt::append(ret, "CR = 0x%08x\n", cr_pack());
|
||||
fmt::append(ret, "LR = 0x%llx\n", lr);
|
||||
fmt::append(ret, "CTR = 0x%llx\n", ctr);
|
||||
fmt::append(ret, "VRSAVE = 0x%08x\n", vrsave);
|
||||
fmt::append(ret, "XER = [CA=%u | OV=%u | SO=%u | CNT=%u]\n", xer.ca, xer.ov, xer.so, xer.cnt);
|
||||
fmt::append(ret, "VSCR = [SAT=%u | NJ=%u]\n", sat, nj);
|
||||
fmt::append(ret, "FPSCR = [FL=%u | FG=%u | FE=%u | FU=%u]\n", fpscr.fl, fpscr.fg, fpscr.fe, fpscr.fu);
|
||||
fmt::append(ret, "\nCall stack:\n=========\n0x%08x (0x0) called\n", g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm ? 0 : cia);
|
||||
|
||||
// TODO: support foreign stack
|
||||
ret += "\nCall stack:\n=========\n";
|
||||
ret += fmt::format("0x%08x (0x0) called\n", g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm ? 0 : cia);
|
||||
const u32 stack_max = ::align(stack_addr + stack_size, 0x200) - 0x200;
|
||||
for (u64 sp = vm::read64(static_cast<u32>(gpr[1])); sp >= stack_addr && sp < stack_max; sp = vm::read64(static_cast<u32>(sp)))
|
||||
// Determine stack range
|
||||
u32 stack_ptr = static_cast<u32>(gpr[1]);
|
||||
u32 stack_min = stack_ptr & ~0xfff;
|
||||
u32 stack_max = stack_min + 4096;
|
||||
|
||||
while (stack_min && vm::check_addr(stack_min - 4096, 4096, vm::page_writable))
|
||||
{
|
||||
stack_min -= 4096;
|
||||
}
|
||||
|
||||
while (stack_max + 4096 && vm::check_addr(stack_max, 4096, vm::page_writable))
|
||||
{
|
||||
stack_max += 4096;
|
||||
}
|
||||
|
||||
for (u64 sp = vm::read64(stack_ptr); sp >= stack_min && sp + 0x200 < stack_max; sp = vm::read64(static_cast<u32>(sp)))
|
||||
{
|
||||
// TODO: print also function addresses
|
||||
ret += fmt::format("> from 0x%08llx (0x0)\n", vm::read64(static_cast<u32>(sp + 16)));
|
||||
fmt::append(ret, "> from 0x%08llx (0x0)\n", vm::read64(static_cast<u32>(sp + 16)));
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -544,7 +560,7 @@ ppu_thread::~ppu_thread()
|
||||
{
|
||||
if (stack_addr)
|
||||
{
|
||||
vm::dealloc_verbose_nothrow(stack_addr, vm::stack);
|
||||
vm::dealloc_verbose_nothrow(stack_addr - 4096, vm::stack);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user