rosalina & pm: properly shutdown when debugger, input redir (but not both) and force connection are enabled

This commit is contained in:
TuxSH 2020-04-28 01:31:29 +01:00
parent 8c54613e44
commit 44cd3928fb
10 changed files with 129 additions and 74 deletions

View File

@ -311,6 +311,11 @@ ProcessData *terminateAllProcesses(u32 callerPid, s64 timeout)
ProcessList_Lock(&g_manager.processList);
// Send custom notification to at least Rosalina to make it relinquish some non-KIP services handles, stop the debugger, etc.
if (numKips >= 6) {
notifySubscribers(0x1001);
}
// Send notification 0x100 to the currently running application
if (g_manager.runningApplicationData != NULL) {
g_manager.runningApplicationData->flags &= ~PROCESSFLAG_DEPENDENCIES_LOADED;

View File

@ -36,4 +36,5 @@ extern int inputRedirectionStartResult;
MyThread *inputRedirectionCreateThread(void);
void inputRedirectionThreadMain(void);
Result InputRedirection_Disable(s64 timeout);
Result InputRedirection_DoOrUndoPatches(void);

View File

@ -32,6 +32,8 @@
extern Menu debuggerMenu;
void debuggerFetchAndSetNextApplicationDebugHandleTask(void *argdata);
Result debuggerDisable(s64 timeout);
void DebuggerMenu_EnableDebugger(void);
void DebuggerMenu_DisableDebugger(void);
void DebuggerMenu_DebugNextApplicationByForce(void);

View File

@ -18,13 +18,10 @@
#include <errno.h>
#define SYNC_ERROR ENODEV
extern Handle SOCU_handle;
extern Handle socMemhandle;
extern bool miniSocEnabled;
Result miniSocInit();
Result miniSocInit(void);
Result miniSocExitDirect(void);
Result miniSocExit(void);
s32 _net_convert_error(s32 sock_retval);

View File

@ -159,14 +159,30 @@ void inputRedirectionThreadMain(void)
linger.l_linger = 0;
socSetsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(struct linger));
socClose(sock);
miniSocExit();
}
void hidCodePatchFunc(void);
void irCodePatchFunc(void);
Result InputRedirection_Disable(s64 timeout)
{
if(!inputRedirectionEnabled)
return 0;
Result res = InputRedirection_DoOrUndoPatches();
if(R_FAILED(res))
return res;
inputRedirectionEnabled = false;
res = MyThread_Join(&inputRedirectionThread, timeout);
svcCloseHandle(inputRedirectionThreadStartedEvent);
return res;
}
Result InputRedirection_DoOrUndoPatches(void)
{
s64 startAddress, textTotalRoundedSize, rodataTotalRoundedSize, dataTotalRoundedSize;

View File

@ -38,6 +38,9 @@
#include "menus/debugger.h"
#include "menus/screen_filters.h"
#include "menus/cheats.h"
#include "menus/sysconfig.h"
#include "input_redirection.h"
#include "minisoc.h"
#include "task_runner.h"
@ -161,6 +164,26 @@ static void handleTermNotification(u32 notificationId)
svcSignalEvent(terminationRequestEvent);
}
static void relinquishConnectionSessions(u32 notificationId)
{
(void)notificationId;
// Might be subject to a race condition, but heh.
// Disable input redirection
InputRedirection_Disable(100 * 1000 * 1000LL);
// Ask the debugger to terminate in approx 2 * 100ms
debuggerDisable(100 * 1000 * 1000LL);
// Kill the ac session if needed
if(isConnectionForced)
{
acExit();
isConnectionForced = false;
SysConfigMenu_UpdateStatus(true);
}
}
static void handleNextApplicationDebuggedByForce(u32 notificationId)
{
(void)notificationId;
@ -175,7 +198,9 @@ static const ServiceManagerServiceEntry services[] = {
static const ServiceManagerNotificationEntry notifications[] = {
{ 0x100 , handleTermNotification },
//{ 0x103 , relinquishConnectionSessions }, // Sleep mode entry <=== causes issues
{ 0x1000, handleNextApplicationDebuggedByForce },
{ 0x1001, relinquishConnectionSessions },
{ 0x000, NULL },
};

View File

@ -84,6 +84,30 @@ void debuggerFetchAndSetNextApplicationDebugHandleTask(void *argdata)
GDB_UnlockAllContexts(&gdbServer);
}
Result debuggerDisable(s64 timeout)
{
Result res = 0;
bool initialized = gdbServer.referenceCount != 0;
if(initialized)
{
svcSignalEvent(gdbServer.super.shall_terminate_event);
server_kill_connections(&gdbServer.super);
res = MyThread_Join(&debuggerDebugThread, timeout);
if(res == 0)
res = MyThread_Join(&debuggerSocketThread, timeout);
Handle dummy = 0;
PMDBG_RunQueuedProcess(&dummy);
svcCloseHandle(dummy);
PMDBG_DebugNextApplicationByForce(false);
nextApplicationGdbCtx = NULL;
svcKernelSetState(0x10000, 2);
}
return res;
}
void DebuggerMenu_EnableDebugger(void)
{
bool done = false, alreadyEnabled = gdbServer.super.running;
@ -144,27 +168,10 @@ void DebuggerMenu_EnableDebugger(void)
void DebuggerMenu_DisableDebugger(void)
{
bool initialized = gdbServer.referenceCount != 0;
Result res = 0;
Result res = initialized ? debuggerDisable(2 * 1000 * 1000 * 1000LL) : 0;
char buf[65];
if(initialized)
{
svcSignalEvent(gdbServer.super.shall_terminate_event);
server_kill_connections(&gdbServer.super);
//server_set_should_close_all(&gdbServer.super);
res = MyThread_Join(&debuggerDebugThread, 2 * 1000 * 1000 * 1000LL);
if(res == 0)
res = MyThread_Join(&debuggerSocketThread, 2 * 1000 * 1000 * 1000LL);
Handle dummy = 0;
PMDBG_RunQueuedProcess(&dummy);
svcCloseHandle(dummy);
PMDBG_DebugNextApplicationByForce(false);
nextApplicationGdbCtx = NULL;
svcKernelSetState(0x10000, 2);
}
if(res != 0)
sprintf(buf, "Failed to disable debugger (0x%08lx).", (u32)res);

View File

@ -221,7 +221,6 @@ void MiscellaneousMenu_SaveSettings(void)
void MiscellaneousMenu_InputRedirection(void)
{
static MyThread *inputRedirectionThread = NULL;
bool done = false;
Result res;
@ -231,11 +230,7 @@ void MiscellaneousMenu_InputRedirection(void)
if(wasEnabled)
{
res = InputRedirection_DoOrUndoPatches();
inputRedirectionEnabled = false;
res = MyThread_Join(inputRedirectionThread, 5 * 1000 * 1000 * 1000LL);
svcCloseHandle(inputRedirectionThreadStartedEvent);
res = InputRedirection_Disable(5 * 1000 * 1000 * 1000LL);
if(res != 0)
sprintf(buf, "Failed to stop InputRedirection (0x%08lx).", (u32)res);
else
@ -282,7 +277,7 @@ void MiscellaneousMenu_InputRedirection(void)
res = svcCreateEvent(&inputRedirectionThreadStartedEvent, RESET_STICKY);
if(R_SUCCEEDED(res))
{
inputRedirectionThread = inputRedirectionCreateThread();
inputRedirectionCreateThread();
res = svcWaitSynchronization(inputRedirectionThreadStartedEvent, 10 * 1000 * 1000 * 1000LL);
if(res == 0)
res = (Result)inputRedirectionStartResult;

View File

@ -13,6 +13,14 @@
#include <3ds/result.h>
#include <string.h>
s32 miniSocRefCount = 0;
static u32 socContextAddr = 0x08000000;
static u32 socContextSize = 0x60000;
static Handle miniSocHandle;
static Handle miniSocMemHandle;
bool miniSocEnabled = false;
s32 _net_convert_error(s32 sock_retval);
static Result SOCU_Initialize(Handle memhandle, u32 memsize)
@ -26,7 +34,7 @@ static Result SOCU_Initialize(Handle memhandle, u32 memsize)
cmdbuf[4] = IPC_Desc_SharedHandles(1);
cmdbuf[5] = memhandle;
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
if(ret != 0)
return ret;
@ -40,22 +48,14 @@ static Result SOCU_Shutdown(void)
cmdbuf[0] = IPC_MakeHeader(0x19,0,0); // 0x190000
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
if(ret != 0)
return ret;
return cmdbuf[1];
}
static s32 miniSocRefCount = 0;
static u32 socContextAddr = 0x08000000;
static u32 socContextSize = 0x60000;
// SOCU_handle from ctrulib
// socMemhandle from ctrulib
bool miniSocEnabled = false;
Result miniSocInit()
Result miniSocInit(void)
{
if(AtomicPostIncrement(&miniSocRefCount))
return 0;
@ -72,7 +72,7 @@ Result miniSocInit()
goto cleanup;
}
ret = srvGetServiceHandle(&SOCU_handle, "soc:U");
ret = srvGetServiceHandle(&miniSocHandle, "soc:U");
if(ret != 0) goto cleanup;
ret = svcControlMemory(&tmp, socContextAddr, 0, socContextSize, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
@ -80,12 +80,12 @@ Result miniSocInit()
socContextAddr = tmp;
ret = svcCreateMemoryBlock(&socMemhandle, (u32)socContextAddr, socContextSize, 0, 3);
ret = svcCreateMemoryBlock(&miniSocMemHandle, (u32)socContextAddr, socContextSize, 0, 3);
if(ret != 0) goto cleanup;
ret = SOCU_Initialize(socMemhandle, socContextSize);
ret = SOCU_Initialize(miniSocMemHandle, socContextSize);
if(ret != 0) goto cleanup;
svcKernelSetState(0x10000, 2);
@ -95,17 +95,17 @@ Result miniSocInit()
cleanup:
AtomicDecrement(&miniSocRefCount);
if(socMemhandle != 0)
if(miniSocMemHandle != 0)
{
svcCloseHandle(socMemhandle);
socMemhandle = 0;
svcCloseHandle(miniSocMemHandle);
miniSocMemHandle = 0;
}
if(SOCU_handle != 0)
if(miniSocHandle != 0)
{
SOCU_Shutdown();
svcCloseHandle(SOCU_handle);
SOCU_handle = 0;
svcCloseHandle(miniSocHandle);
miniSocHandle = 0;
}
if(tmp != 0)
@ -114,21 +114,19 @@ cleanup:
return ret;
}
Result miniSocExit(void)
Result miniSocExitDirect(void)
{
if(AtomicDecrement(&miniSocRefCount))
return 0;
//if (miniSocRefCount != 0) __builtin_trap();
Result ret = 0;
u32 tmp;
svcCloseHandle(socMemhandle);
socMemhandle = 0;
svcCloseHandle(miniSocMemHandle);
miniSocMemHandle = 0;
ret = SOCU_Shutdown();
svcCloseHandle(SOCU_handle);
SOCU_handle = 0;
svcCloseHandle(miniSocHandle);
miniSocHandle = 0;
svcControlMemory(&tmp, socContextAddr, socContextAddr, socContextSize, MEMOP_FREE, MEMPERM_DONTCARE);
if(ret == 0)
@ -139,6 +137,14 @@ Result miniSocExit(void)
return ret;
}
Result miniSocExit(void)
{
if(!miniSocEnabled || AtomicDecrement(&miniSocRefCount))
return 0;
return miniSocExitDirect();
}
int socSocket(int domain, int type, int protocol)
{
int ret = 0;
@ -164,7 +170,7 @@ int socSocket(int domain, int type, int protocol)
cmdbuf[3] = protocol;
cmdbuf[4] = IPC_Desc_CurProcessId();
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
if(ret != 0)
{
//errno = SYNC_ERROR;
@ -214,7 +220,7 @@ int socBind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
cmdbuf[6] = (u32)tmpaddr;
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
if(ret != 0) {
//errno = SYNC_ERROR;
return ret;
@ -242,7 +248,7 @@ int socListen(int sockfd, int max_connections)
cmdbuf[2] = (u32)max_connections;
cmdbuf[3] = IPC_Desc_CurProcessId();
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
if(ret != 0)
{
//errno = SYNC_ERROR;
@ -284,7 +290,7 @@ int socAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
staticbufs[1] = (u32)tmpaddr;
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
staticbufs[0] = saved_threadstorage[0];
staticbufs[1] = saved_threadstorage[1];
@ -341,7 +347,7 @@ int socConnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
cmdbuf[6] = (u32)tmpaddr;
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
if(ret != 0) return -1;
ret = (int)cmdbuf[1];
@ -384,7 +390,7 @@ int socPoll(struct pollfd *fds, nfds_t nfds, int timeout)
staticbufs[0] = IPC_Desc_StaticBuffer(size,0);
staticbufs[1] = (u32)fds;
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
staticbufs[0] = saved_threadstorage[0];
staticbufs[1] = saved_threadstorage[1];
@ -409,7 +415,7 @@ int socClose(int sockfd)
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = IPC_Desc_CurProcessId();
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
if(ret != 0) {
//errno = SYNC_ERROR;
return ret;
@ -441,7 +447,7 @@ int socSetsockopt(int sockfd, int level, int optname, const void *optval, sockle
cmdbuf[7] = IPC_Desc_StaticBuffer(optlen,9);
cmdbuf[8] = (u32)optval;
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
if(ret != 0) {
return ret;
}
@ -465,7 +471,7 @@ long socGethostid(void)
cmdbuf[0] = IPC_MakeHeader(0x16,0,0); // 0x160000
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
if(ret != 0) {
//errno = SYNC_ERROR;
return -1;
@ -507,7 +513,7 @@ static ssize_t _socuipc_cmd7(int sockfd, void *buf, size_t len, int flags, struc
staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
staticbufs[1] = (u32)tmpaddr;
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
staticbufs[0] = saved_threadstorage[0];
staticbufs[1] = saved_threadstorage[1];
@ -566,7 +572,7 @@ static ssize_t _socuipc_cmd8(int sockfd, void *buf, size_t len, int flags, struc
cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2;
cmdbuf[0x10c>>2] = (u32)tmpaddr;
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
if(ret != 0) {
//errno = SYNC_ERROR;
return ret;
@ -632,7 +638,7 @@ static ssize_t _socuipc_cmd9(int sockfd, const void *buf, size_t len, int flags,
cmdbuf[9] = IPC_Desc_Buffer(len,IPC_BUFFER_R);
cmdbuf[10] = (u32)buf;
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
if(ret != 0) {
//errno = SYNC_ERROR;
return ret;
@ -686,7 +692,7 @@ static ssize_t _socuipc_cmda(int sockfd, const void *buf, size_t len, int flags,
cmdbuf[9] = IPC_Desc_StaticBuffer(tmp_addrlen,1);
cmdbuf[10] = (u32)tmpaddr;
ret = svcSendSyncRequest(SOCU_handle);
ret = svcSendSyncRequest(miniSocHandle);
if(ret != 0) {
//errno = SYNC_ERROR;
return ret;

View File

@ -301,7 +301,8 @@ void server_kill_connections(struct sock_server *serv)
socClose(fds[i].fd);
fds[i].fd = -1;
serv->ctx_ptrs[i]->should_close = true;
if(serv->ctx_ptrs[i] != NULL)
serv->ctx_ptrs[i]->should_close = true;
}
}