libdebugger: Add a target break call to suspend all running threads

- Optionally wait if there is no remote debugger connected and break
  when the remote connects

Closes #4740
This commit is contained in:
Chris Johns
2022-10-17 16:25:57 +11:00
parent 1d2fab8a79
commit d574e08663
3 changed files with 65 additions and 16 deletions

View File

@@ -103,6 +103,7 @@ extern "C" {
#define RTEMS_DEBUGGER_FLAG_MULTIPROCESS (1 << 4) #define RTEMS_DEBUGGER_FLAG_MULTIPROCESS (1 << 4)
#define RTEMS_DEBUGGER_FLAG_VERBOSE_LOCK (1 << 5) #define RTEMS_DEBUGGER_FLAG_VERBOSE_LOCK (1 << 5)
#define RTEMS_DEBUGGER_FLAG_VERBOSE_CMDS (1 << 6) #define RTEMS_DEBUGGER_FLAG_VERBOSE_CMDS (1 << 6)
#define RTEMS_DEBUGGER_FLAG_BREAK_WAITER (1 << 7)
/** /**
* Forward decl for the threads and targets. * Forward decl for the threads and targets.

View File

@@ -53,6 +53,14 @@ extern int rtems_debugger_start(const char* remote,
rtems_task_priority priority, rtems_task_priority priority,
const rtems_printer* printer); const rtems_printer* printer);
/**
* Suspend all running threads including the caller if not
* excluded. Returns when the debugger has connected and continued.
*
* If wait is true and there is no remote connected wait then break.
*/
extern int rtems_debugger_break(bool wait);
/** /**
* Stop the Debugger. * Stop the Debugger.
*/ */

View File

@@ -1678,18 +1678,30 @@ rtems_debugger_events(rtems_task_argument arg)
rtems_debugger_target_enable(); rtems_debugger_target_enable();
while (rtems_debugger_server_events_running()) { if (rtems_debugger_server_flag(RTEMS_DEBUGGER_FLAG_BREAK_WAITER)) {
rtems_debugger_server_events_wait(); rtems_debugger->flags &= ~RTEMS_DEBUGGER_FLAG_BREAK_WAITER;
if (rtems_debugger_verbose())
rtems_debugger_printf("rtems-db: event woken\n");
if (!rtems_debugger_server_events_running())
break;
r = rtems_debugger_thread_system_suspend(); r = rtems_debugger_thread_system_suspend();
if (r < 0) if (rtems_debugger_verbose())
break; rtems_debugger_printf("rtems-db: break waiter\n");
r = remote_stop_reason(NULL, 0); rtems_debugger_server_events_signal();
if (r < 0) if (rtems_debugger_verbose())
break; rtems_debugger_printf("rtems-db: break waiter: signalled\n");
}
if (r == 0) {
while (rtems_debugger_server_events_running()) {
rtems_debugger_server_events_wait();
if (rtems_debugger_verbose())
rtems_debugger_printf("rtems-db: event woken\n");
if (!rtems_debugger_server_events_running())
break;
r = rtems_debugger_thread_system_suspend();
if (r < 0)
break;
r = remote_stop_reason(NULL, 0);
if (r < 0)
break;
}
} }
if (r < 0) if (r < 0)
@@ -1972,6 +1984,30 @@ rtems_debugger_server_crash(void)
rtems_debugger->remote->end(rtems_debugger->remote); rtems_debugger->remote->end(rtems_debugger->remote);
} }
int
rtems_debugger_break(bool wait)
{
int r = 0;
if (!rtems_debugger_running()) {
errno = EIO;
r = -1;
} else {
rtems_debugger_lock();
if (rtems_debugger_server_events_running()) {
rtems_debugger_server_events_signal();
} else if (
wait && !rtems_debugger_server_flag(RTEMS_DEBUGGER_FLAG_BREAK_WAITER)) {
rtems_debugger->flags |= RTEMS_DEBUGGER_FLAG_BREAK_WAITER;
rtems_debugger_server_events_wait();
} else {
errno = EIO;
r = -1;
}
rtems_debugger_unlock();
}
return r;
}
int int
rtems_debugger_stop(void) rtems_debugger_stop(void)
{ {
@@ -1998,10 +2034,14 @@ rtems_debugger_set_verbose(bool on)
int int
rtems_debugger_remote_debug(bool state) rtems_debugger_remote_debug(bool state)
{ {
rtems_debugger_lock(); if (rtems_debugger_running()) {
rtems_debugger->remote_debug = state; rtems_debugger_lock();
rtems_debugger_printf("rtems-db: remote-debug is %s\n", rtems_debugger->remote_debug = state;
rtems_debugger->remote_debug ? "on" : "off"); rtems_debugger_printf("rtems-db: remote-debug is %s\n",
rtems_debugger_unlock(); rtems_debugger->remote_debug ? "on" : "off");
rtems_debugger_unlock();
} else {
rtems_debugger_printf("rtems-db: debug server not running\n");
}
return 0; return 0;
} }