mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
kern: resolve final non-user-exception MESOSPHERE_UNIMPLEMENTED
This commit is contained in:
parent
85f533e6c4
commit
bea550ebce
1 changed files with 83 additions and 1 deletions
|
@ -879,7 +879,81 @@ namespace ams::kern {
|
|||
}
|
||||
|
||||
Result KDebugBase::ProcessDebugEvent(ams::svc::DebugEvent event, uintptr_t param0, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4) {
|
||||
MESOSPHERE_UNIMPLEMENTED();
|
||||
/* Get the current process. */
|
||||
KProcess *process = GetCurrentProcessPointer();
|
||||
|
||||
/* If the event is AttachThread and we've already attached, there's nothing to do. */
|
||||
if (event == ams::svc::DebugEvent_AttachThread) {
|
||||
R_SUCCEED_IF(GetCurrentThread().IsAttachedToDebugger());
|
||||
}
|
||||
|
||||
while (true) {
|
||||
/* Lock the process and the scheduler. */
|
||||
KScopedLightLock state_lk(process->GetStateLock());
|
||||
KScopedLightLock list_lk(process->GetListLock());
|
||||
KScopedSchedulerLock sl;
|
||||
|
||||
/* If the current thread is terminating, we can't process an event. */
|
||||
R_SUCCEED_IF(GetCurrentThread().IsTerminationRequested());
|
||||
|
||||
/* Get the debug object. If we have none, there's nothing to process. */
|
||||
KDebugBase *debug = GetDebugObject(process);
|
||||
R_SUCCEED_IF(debug == nullptr);
|
||||
|
||||
/* If the event is an exception and we don't have exception events enabled, we can't handle the event. */
|
||||
if (event == ams::svc::DebugEvent_Exception && (debug->continue_flags & ams::svc::ContinueFlag_EnableExceptionEvent) == 0) {
|
||||
GetCurrentThread().SetDebugExceptionResult(ResultSuccess());
|
||||
return svc::ResultNotHandled();
|
||||
}
|
||||
|
||||
/* If the current thread is suspended, retry. */
|
||||
if (GetCurrentThread().IsSuspended()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Suspend all the process's threads. */
|
||||
{
|
||||
auto end = process->GetThreadList().end();
|
||||
for (auto it = process->GetThreadList().begin(); it != end; ++it) {
|
||||
it->RequestSuspend(KThread::SuspendType_Debug);
|
||||
}
|
||||
}
|
||||
|
||||
/* Push the event. */
|
||||
debug->PushDebugEvent(event, param0, param1, param2, param3, param4);
|
||||
debug->NotifyAvailable();
|
||||
|
||||
/* Set the process as breaked. */
|
||||
process->SetDebugBreak();
|
||||
|
||||
/* If the event is an exception, set the result. */
|
||||
if (event == ams::svc::DebugEvent_Exception) {
|
||||
GetCurrentThread().SetDebugExceptionResult(ResultSuccess());
|
||||
}
|
||||
|
||||
/* Exit our retry loop. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the event is an exception, get the exception result. */
|
||||
if (event == ams::svc::DebugEvent_Exception) {
|
||||
/* Lock the scheduler. */
|
||||
KScopedSchedulerLock sl;
|
||||
|
||||
/* If the thread is terminating, we can't process the exception. */
|
||||
R_UNLESS(!GetCurrentThread().IsTerminationRequested(), svc::ResultStopProcessingException());
|
||||
|
||||
/* Get the debug object. */
|
||||
if (KDebugBase *debug = GetDebugObject(process); debug != nullptr) {
|
||||
/* If we have one, check the debug exception. */
|
||||
return GetCurrentThread().GetDebugExceptionResult();
|
||||
} else {
|
||||
/* We don't have a debug object, so stop processing the exception. */
|
||||
return svc::ResultStopProcessingException();
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result KDebugBase::OnDebugEvent(ams::svc::DebugEvent event, uintptr_t param0, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4) {
|
||||
|
@ -892,9 +966,12 @@ namespace ams::kern {
|
|||
Result KDebugBase::OnExitProcess(KProcess *process) {
|
||||
MESOSPHERE_ASSERT(process != nullptr);
|
||||
|
||||
/* Check if we're attached to a debugger. */
|
||||
if (process->IsAttachedToDebugger()) {
|
||||
/* If we are, lock the scheduler. */
|
||||
KScopedSchedulerLock sl;
|
||||
|
||||
/* Push the event. */
|
||||
if (KDebugBase *debug = GetDebugObject(process); debug != nullptr) {
|
||||
debug->PushDebugEvent(ams::svc::DebugEvent_ExitProcess, ams::svc::ProcessExitReason_ExitProcess);
|
||||
debug->NotifyAvailable();
|
||||
|
@ -907,9 +984,12 @@ namespace ams::kern {
|
|||
Result KDebugBase::OnTerminateProcess(KProcess *process) {
|
||||
MESOSPHERE_ASSERT(process != nullptr);
|
||||
|
||||
/* Check if we're attached to a debugger. */
|
||||
if (process->IsAttachedToDebugger()) {
|
||||
/* If we are, lock the scheduler. */
|
||||
KScopedSchedulerLock sl;
|
||||
|
||||
/* Push the event. */
|
||||
if (KDebugBase *debug = GetDebugObject(process); debug != nullptr) {
|
||||
debug->PushDebugEvent(ams::svc::DebugEvent_ExitProcess, ams::svc::ProcessExitReason_TerminateProcess);
|
||||
debug->NotifyAvailable();
|
||||
|
@ -922,7 +1002,9 @@ namespace ams::kern {
|
|||
Result KDebugBase::OnExitThread(KThread *thread) {
|
||||
MESOSPHERE_ASSERT(thread != nullptr);
|
||||
|
||||
/* Check if we're attached to a debugger. */
|
||||
if (KProcess *process = thread->GetOwnerProcess(); process != nullptr && process->IsAttachedToDebugger()) {
|
||||
/* If we are, submit the event. */
|
||||
R_TRY(OnDebugEvent(ams::svc::DebugEvent_ExitThread, thread->GetId(), thread->IsTerminationRequested() ? ams::svc::ThreadExitReason_TerminateThread : ams::svc::ThreadExitReason_ExitThread));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue