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; extern Menu debuggerMenu;
void debuggerSetNextApplicationDebugHandle(Handle debug); void debuggerFetchAndSetNextApplicationDebugHandleTask(void *argdata);
void DebuggerMenu_EnableDebugger(void); void DebuggerMenu_EnableDebugger(void);
void DebuggerMenu_DisableDebugger(void); void DebuggerMenu_DisableDebugger(void);
void DebuggerMenu_DebugNextApplicationByForce(void); void DebuggerMenu_DebugNextApplicationByForce(void);

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <3ds/services/pmapp.h> #include <3ds/services/pmapp.h>
#include <3ds/services/pmdbg.h>
Result PMDBG_GetCurrentAppTitleIdAndPid(u64 *outTitleId, u32 *outPid); Result PMDBG_GetCurrentAppTitleIdAndPid(u64 *outTitleId, u32 *outPid);
Result PMDBG_DebugNextApplicationByForce(void); 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/watchpoints.h"
#include "gdb/breakpoints.h" #include "gdb/breakpoints.h"
#include "gdb/stop_point.h" #include "gdb/stop_point.h"
#include "task_runner.h"
Result GDB_InitializeServer(GDBServer *server) Result GDB_InitializeServer(GDBServer *server)
{ {
@ -225,6 +226,10 @@ GDBContext *GDB_GetClient(GDBServer *server, u16 port)
GDB_UnlockAllContexts(server); GDB_UnlockAllContexts(server);
return NULL; 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->flags |= GDB_FLAG_USED;
ctx->state = GDB_STATE_CONNECTED; ctx->state = GDB_STATE_CONNECTED;
ctx->parent = server; ctx->parent = server;

View File

@ -38,6 +38,8 @@
#include "menus/debugger.h" #include "menus/debugger.h"
#include "menus/screen_filters.h" #include "menus/screen_filters.h"
#include "task_runner.h"
static Result stealFsReg(void) static Result stealFsReg(void)
{ {
Result ret = 0; Result ret = 0;
@ -157,10 +159,10 @@ static void handleTermNotification(u32 notificationId)
static void handleNextApplicationDebuggedByForce(u32 notificationId) static void handleNextApplicationDebuggedByForce(u32 notificationId)
{ {
int dummy;
(void)notificationId; (void)notificationId;
Handle debug = 0; // Following call needs to be async because pm -> Loader depends on rosalina hb:ldr, handled in this very thread.
PMDBG_RunQueuedProcess(&debug); TaskRunner_RunTask(debuggerFetchAndSetNextApplicationDebugHandleTask, &dummy, 0);
debuggerSetNextApplicationDebugHandle(debug);
} }
static const ServiceManagerServiceEntry services[] = { static const ServiceManagerServiceEntry services[] = {
@ -191,11 +193,13 @@ int main(void)
svcBreak(USERBREAK_ASSERT); svcBreak(USERBREAK_ASSERT);
MyThread *menuThread = menuCreateThread(); MyThread *menuThread = menuCreateThread();
MyThread *taskRunnerThread = taskRunnerCreateThread();
if (R_FAILED(ServiceManager_Run(services, notifications, NULL))) if (R_FAILED(ServiceManager_Run(services, notifications, NULL)))
svcBreak(USERBREAK_PANIC); svcBreak(USERBREAK_PANIC);
MyThread_Join(menuThread, -1LL); MyThread_Join(menuThread, -1LL);
MyThread_Join(taskRunnerThread, -1LL);
return 0; return 0;
} }

View File

@ -34,6 +34,7 @@
#include "gdb/debug.h" #include "gdb/debug.h"
#include "gdb/monitor.h" #include "gdb/monitor.h"
#include "gdb/net.h" #include "gdb/net.h"
#include "pmdbgext.h"
Menu debuggerMenu = { Menu debuggerMenu = {
"Debugger options menu", "Debugger options menu",
@ -68,8 +69,11 @@ MyThread *debuggerCreateDebugThread(void)
return &debuggerDebugThread; return &debuggerDebugThread;
} }
void debuggerSetNextApplicationDebugHandle(Handle debug) void debuggerFetchAndSetNextApplicationDebugHandleTask(void *argdata)
{ {
(void)argdata;
Handle debug = 0;
PMDBG_RunQueuedProcess(&debug);
GDB_LockAllContexts(&gdbServer); GDB_LockAllContexts(&gdbServer);
nextApplicationGdbCtx->debug = debug; nextApplicationGdbCtx->debug = debug;
if (debug == 0) 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);
}