Fix "debug next process" with hbldr homebrew
This commit is contained in:
parent
9e1a9f2842
commit
eef22f8701
@ -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);
|
||||||
|
@ -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);
|
||||||
|
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/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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
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