Fix "debug next process" with hbldr homebrew
This commit is contained in:
parent
9e1a9f2842
commit
eef22f8701
@ -31,7 +31,7 @@
|
||||
|
||||
extern Menu debuggerMenu;
|
||||
|
||||
void debuggerSetNextApplicationDebugHandle(Handle debug);
|
||||
void debuggerFetchAndSetNextApplicationDebugHandleTask(void *argdata);
|
||||
void DebuggerMenu_EnableDebugger(void);
|
||||
void DebuggerMenu_DisableDebugger(void);
|
||||
void DebuggerMenu_DebugNextApplicationByForce(void);
|
||||
|
@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds/services/pmapp.h>
|
||||
#include <3ds/services/pmdbg.h>
|
||||
|
||||
Result PMDBG_GetCurrentAppTitleIdAndPid(u64 *outTitleId, u32 *outPid);
|
||||
Result PMDBG_DebugNextApplicationByForce(void);
|
||||
|
22
sysmodules/rosalina/include/task_runner.h
Normal file
22
sysmodules/rosalina/include/task_runner.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/synchronization.h>
|
||||
#include "MyThread.h"
|
||||
|
||||
typedef struct TaskRunner {
|
||||
LightEvent readyEvent;
|
||||
LightEvent parametersSetEvent;
|
||||
void (*task)(void *argdata);
|
||||
u8 argStorage[0x40];
|
||||
} TaskRunner;
|
||||
|
||||
extern TaskRunner g_taskRunner;
|
||||
|
||||
MyThread *taskRunnerCreateThread(void);
|
||||
|
||||
void TaskRunner_Init(void);
|
||||
void TaskRunner_RunTask(void (*task)(void *argdata), void *argdata, size_t argsize);
|
||||
/// Thread function
|
||||
void TaskRunner_HandleTasks(void);
|
||||
void TaskRunner_WaitReady(void);
|
@ -36,6 +36,7 @@
|
||||
#include "gdb/watchpoints.h"
|
||||
#include "gdb/breakpoints.h"
|
||||
#include "gdb/stop_point.h"
|
||||
#include "task_runner.h"
|
||||
|
||||
Result GDB_InitializeServer(GDBServer *server)
|
||||
{
|
||||
@ -225,6 +226,10 @@ GDBContext *GDB_GetClient(GDBServer *server, u16 port)
|
||||
GDB_UnlockAllContexts(server);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctx->localPort == GDB_PORT_BASE + MAX_DEBUG)
|
||||
TaskRunner_WaitReady(); // Finish grabbing new process debug, if anything...
|
||||
|
||||
ctx->flags |= GDB_FLAG_USED;
|
||||
ctx->state = GDB_STATE_CONNECTED;
|
||||
ctx->parent = server;
|
||||
|
@ -38,6 +38,8 @@
|
||||
#include "menus/debugger.h"
|
||||
#include "menus/screen_filters.h"
|
||||
|
||||
#include "task_runner.h"
|
||||
|
||||
static Result stealFsReg(void)
|
||||
{
|
||||
Result ret = 0;
|
||||
@ -157,10 +159,10 @@ static void handleTermNotification(u32 notificationId)
|
||||
|
||||
static void handleNextApplicationDebuggedByForce(u32 notificationId)
|
||||
{
|
||||
int dummy;
|
||||
(void)notificationId;
|
||||
Handle debug = 0;
|
||||
PMDBG_RunQueuedProcess(&debug);
|
||||
debuggerSetNextApplicationDebugHandle(debug);
|
||||
// Following call needs to be async because pm -> Loader depends on rosalina hb:ldr, handled in this very thread.
|
||||
TaskRunner_RunTask(debuggerFetchAndSetNextApplicationDebugHandleTask, &dummy, 0);
|
||||
}
|
||||
|
||||
static const ServiceManagerServiceEntry services[] = {
|
||||
@ -191,11 +193,13 @@ int main(void)
|
||||
svcBreak(USERBREAK_ASSERT);
|
||||
|
||||
MyThread *menuThread = menuCreateThread();
|
||||
MyThread *taskRunnerThread = taskRunnerCreateThread();
|
||||
|
||||
if (R_FAILED(ServiceManager_Run(services, notifications, NULL)))
|
||||
svcBreak(USERBREAK_PANIC);
|
||||
|
||||
MyThread_Join(menuThread, -1LL);
|
||||
MyThread_Join(taskRunnerThread, -1LL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "gdb/debug.h"
|
||||
#include "gdb/monitor.h"
|
||||
#include "gdb/net.h"
|
||||
#include "pmdbgext.h"
|
||||
|
||||
Menu debuggerMenu = {
|
||||
"Debugger options menu",
|
||||
@ -68,8 +69,11 @@ MyThread *debuggerCreateDebugThread(void)
|
||||
return &debuggerDebugThread;
|
||||
}
|
||||
|
||||
void debuggerSetNextApplicationDebugHandle(Handle debug)
|
||||
void debuggerFetchAndSetNextApplicationDebugHandleTask(void *argdata)
|
||||
{
|
||||
(void)argdata;
|
||||
Handle debug = 0;
|
||||
PMDBG_RunQueuedProcess(&debug);
|
||||
GDB_LockAllContexts(&gdbServer);
|
||||
nextApplicationGdbCtx->debug = debug;
|
||||
if (debug == 0)
|
||||
|
45
sysmodules/rosalina/source/task_runner.c
Normal file
45
sysmodules/rosalina/source/task_runner.c
Normal file
@ -0,0 +1,45 @@
|
||||
#include <3ds.h>
|
||||
#include <string.h>
|
||||
#include "task_runner.h"
|
||||
|
||||
TaskRunner g_taskRunner;
|
||||
|
||||
static MyThread taskRunnerThread;
|
||||
static u8 ALIGN(8) taskRunnerThreadStack[0x1000];
|
||||
|
||||
MyThread *taskRunnerCreateThread(void)
|
||||
{
|
||||
TaskRunner_Init();
|
||||
MyThread_Create(&taskRunnerThread, TaskRunner_HandleTasks, taskRunnerThreadStack, THREAD_STACK_SIZE, 0x20, 1);
|
||||
return &taskRunnerThread;
|
||||
}
|
||||
|
||||
void TaskRunner_Init(void)
|
||||
{
|
||||
memset(&g_taskRunner, 0, sizeof(TaskRunner));
|
||||
LightEvent_Init(&g_taskRunner.readyEvent, RESET_ONESHOT);
|
||||
LightEvent_Init(&g_taskRunner.parametersSetEvent, RESET_ONESHOT);
|
||||
}
|
||||
|
||||
void TaskRunner_RunTask(void (*task)(void *argdata), void *argdata, size_t argsize)
|
||||
{
|
||||
argsize = argsize > sizeof(g_taskRunner.argStorage) ? sizeof(g_taskRunner.argStorage) : argsize;
|
||||
LightEvent_Wait(&g_taskRunner.readyEvent);
|
||||
g_taskRunner.task = task;
|
||||
memcpy(g_taskRunner.argStorage, argdata, argsize);
|
||||
LightEvent_Signal(&g_taskRunner.parametersSetEvent);
|
||||
}
|
||||
|
||||
void TaskRunner_HandleTasks(void)
|
||||
{
|
||||
for (;;) {
|
||||
LightEvent_Signal(&g_taskRunner.readyEvent);
|
||||
LightEvent_Wait(&g_taskRunner.parametersSetEvent);
|
||||
g_taskRunner.task(g_taskRunner.argStorage);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskRunner_WaitReady(void)
|
||||
{
|
||||
LightEvent_Wait(&g_taskRunner.readyEvent);
|
||||
}
|
Reference in New Issue
Block a user