dmnt2: first pass at wait-for-application

This commit is contained in:
Michael Scire 2021-10-31 23:57:28 -07:00
parent 56669e34b7
commit 9011384dbe
6 changed files with 39 additions and 9 deletions

View file

@ -27,10 +27,15 @@ namespace ams::dmnt {
}
Result DebugProcess::Attach(os::ProcessId process_id) {
Result DebugProcess::Attach(os::ProcessId process_id, bool start_process) {
/* Attach to the process. */
R_TRY(svc::DebugActiveProcess(std::addressof(m_debug_handle), process_id.value));
/* If necessary, start the process. */
if (start_process) {
R_ABORT_UNLESS(pm::dmnt::StartProcess(process_id));
}
/* Collect initial information. */
R_TRY(this->Start());

View file

@ -109,7 +109,7 @@ namespace ams::dmnt {
m_status = ProcessStatus_DebugBreak;
}
public:
Result Attach(os::ProcessId process_id);
Result Attach(os::ProcessId process_id, bool start_process = false);
void Detach();
Result GetThreadContext(svc::ThreadContext *out, u64 thread_id, u32 flags);

View file

@ -857,12 +857,19 @@ namespace ams::dmnt {
/* Detach. */
m_debug_process.Detach();
/* Check if we need to start the process. */
const bool start_process = m_process_id == m_wait_process_id;
{
/* Clear our wait process id. */
ON_SCOPE_EXIT { if (start_process) { m_wait_process_id = os::InvalidProcessId; } };
/* If we have a process id, attach. */
if (R_FAILED(m_debug_process.Attach(m_process_id))) {
if (R_FAILED(m_debug_process.Attach(m_process_id, m_process_id == m_wait_process_id))) {
AMS_DMNT2_GDB_LOG_DEBUG("Failed to attach to %016lx\n", m_process_id.value);
g_event_done_cv.Signal();
continue;
}
}
/* Set our process id. */
m_process_id = m_debug_process.GetProcessId();
@ -1882,7 +1889,22 @@ namespace ams::dmnt {
}
}
} else if (ParsePrefix(command, "wait application") || ParsePrefix(command, "wait app")) {
SetReply(m_buffer, "[TODO] wait for next application\n");
/* Wait for an application process. */
{
/* Get hook to creation of application process. */
os::NativeHandle h;
R_ABORT_UNLESS(pm::dmnt::HookToCreateApplicationProcess(std::addressof(h)));
/* Wait for event. */
os::SystemEvent hook_event(h, true, os::InvalidNativeHandle, false, os::EventClearMode_AutoClear);
hook_event.Wait();
}
/* Get application process id. */
R_ABORT_UNLESS(pm::dmnt::GetApplicationProcessId(std::addressof(m_wait_process_id)));
/* Note that we're attaching. */
SetReply(m_buffer, "Attach to 0x%lx.\n", m_wait_process_id.value);
} else if (ParsePrefix(command, "wait homebrew") || ParsePrefix(command, "wait hb")) {
SetReply(m_buffer, "[TODO] wait for next homebrew\n");
} else if (ParsePrefix(command, "wait ")) {

View file

@ -42,6 +42,7 @@ namespace ams::dmnt {
DebugProcess m_debug_process;
os::ProcessId m_process_id{os::InvalidProcessId};
os::Event m_event;
os::ProcessId m_wait_process_id{os::InvalidProcessId};
public:
GdbServerImpl(int socket, void *thread_stack, size_t stack_size);
~GdbServerImpl();

View file

@ -42,6 +42,9 @@ namespace ams {
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize());
/* Initialize other services we need. */
R_ABORT_UNLESS(pmdmntInitialize());
/* Verify that we can sanely execute. */
ams::CheckApiVersion();
}

View file

@ -248,7 +248,6 @@ namespace ams::dmnt::cheat::impl {
void StartProcess(os::ProcessId process_id) const {
R_ABORT_UNLESS(pm::dmnt::StartProcess(process_id));
}
public:
CheatProcessManager() : m_cheat_lock(), m_unsafe_break_event(os::EventClearMode_ManualClear), m_debug_events_event(os::EventClearMode_AutoClear), m_cheat_process_event(os::EventClearMode_AutoClear, true) {
/* Learn whether we should enable cheats by default. */