Fix "debug next process" with hbldr homebrew

This commit is contained in:
TuxSH 2019-04-18 22:58:53 +02:00
parent 9e1a9f2842
commit eef22f8701
7 changed files with 86 additions and 5 deletions

View File

@ -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);

View File

@ -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);

View 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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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)

View 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);
}