mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 08:33:12 -05:00
sceCoredumpAttachMemoryRegion and sceCoredumpAttachUserMemoryFile take (uint32_t userValue, const void* mem, size_t size): the Orbital IDA type database and the SharpProspero bindings agree on the first, the second has only SharpProspero. Attaching belongs inside the core dump handler the system runs after the process stops; a call from anywhere else gets SCE_COREDUMP_ERROR_NOT_IN_COREDUMP_HANDLER. The handler is never invoked here, so every call returns that error and nothing is recorded. Whether the console checks the region before the calling context is unknown, so a null, empty or wrapping region throws. The error value 0x81180003 is inferred from fpPS4's 0x81180001 and 0x81180002 and the numbering of the Vita's SceCoredump error table; TechnicalDebt records the sources and what remains unverified. guest_coredump_attach: the error before, during and after a handler registration, from another thread too, without running the handler or touching the region; null, empty and wrapping regions throw naming the function.
68 lines
3.1 KiB
C++
68 lines
3.1 KiB
C++
#include "prx/libc/include/general/VabiMacros.hpp"
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <stdexcept>
|
|
#include <thread>
|
|
|
|
extern "C" {
|
|
int APS5_VABI sceCoredumpRegisterCoredumpHandler(uint64_t handler, size_t stackSize, uint64_t context);
|
|
int APS5_VABI sceCoredumpUnregisterCoredumpHandler(void);
|
|
int APS5_VABI sceCoredumpAttachMemoryRegion(uint32_t userValue, const void* mem, size_t size);
|
|
int APS5_VABI sceCoredumpAttachUserMemoryFile(uint32_t userValue, const void* mem, size_t size);
|
|
}
|
|
|
|
namespace {
|
|
constexpr int NotInCoredumpHandler = static_cast<int>(0x81180003u);
|
|
constexpr uint32_t UserFileTruncateIfExceedLimit = 0x80000000u;
|
|
bool handlerRan = false;
|
|
int handlerContext = 0;
|
|
|
|
int APS5_VABI Handler(void*) {
|
|
handlerRan = true;
|
|
return 0;
|
|
}
|
|
|
|
void Require(bool value) { if (!value) std::abort(); }
|
|
|
|
template <typename TAttach>
|
|
bool Throws(TAttach attach, const char* function) {
|
|
try { attach(); }
|
|
catch (const std::runtime_error& error) { return std::strstr(error.what(), function) != nullptr; }
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
std::array<unsigned char, 64> region{};
|
|
for (size_t index = 0; index < region.size(); ++index) region[index] = static_cast<unsigned char>(index * 7 + 3);
|
|
const auto original = region;
|
|
|
|
Require(sceCoredumpAttachMemoryRegion(1, region.data(), region.size()) == NotInCoredumpHandler);
|
|
Require(sceCoredumpAttachUserMemoryFile(UserFileTruncateIfExceedLimit | 2, region.data(), region.size()) == NotInCoredumpHandler);
|
|
|
|
Require(sceCoredumpRegisterCoredumpHandler(reinterpret_cast<uint64_t>(&Handler), 16 * 1024, reinterpret_cast<uint64_t>(&handlerContext)) == 0);
|
|
Require(sceCoredumpAttachMemoryRegion(0, region.data(), 1) == NotInCoredumpHandler);
|
|
Require(sceCoredumpAttachUserMemoryFile(0xFFFFFFFFu, region.data(), region.size()) == NotInCoredumpHandler);
|
|
int fromThread = 0;
|
|
std::thread([&] { fromThread = sceCoredumpAttachMemoryRegion(3, region.data(), region.size()); }).join();
|
|
Require(fromThread == NotInCoredumpHandler);
|
|
Require(!handlerRan);
|
|
|
|
Require(Throws([&] { sceCoredumpAttachMemoryRegion(1, nullptr, region.size()); }, "sceCoredumpAttachMemoryRegion"));
|
|
Require(Throws([&] { sceCoredumpAttachMemoryRegion(1, region.data(), 0); }, "sceCoredumpAttachMemoryRegion"));
|
|
Require(Throws([&] { sceCoredumpAttachMemoryRegion(1, region.data(), SIZE_MAX); }, "sceCoredumpAttachMemoryRegion"));
|
|
Require(Throws([&] { sceCoredumpAttachUserMemoryFile(1, nullptr, region.size()); }, "sceCoredumpAttachUserMemoryFile"));
|
|
Require(Throws([&] { sceCoredumpAttachUserMemoryFile(1, region.data(), 0); }, "sceCoredumpAttachUserMemoryFile"));
|
|
Require(Throws([&] { sceCoredumpAttachUserMemoryFile(1, region.data(), SIZE_MAX); }, "sceCoredumpAttachUserMemoryFile"));
|
|
|
|
Require(sceCoredumpUnregisterCoredumpHandler() == 0);
|
|
Require(sceCoredumpAttachMemoryRegion(1, region.data(), region.size()) == NotInCoredumpHandler);
|
|
Require(sceCoredumpAttachUserMemoryFile(1, region.data(), region.size()) == NotInCoredumpHandler);
|
|
Require(region == original);
|
|
Require(!handlerRan);
|
|
return 0;
|
|
}
|