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,6 +1678,17 @@ rtems_debugger_events(rtems_task_argument arg)
rtems_debugger_target_enable(); rtems_debugger_target_enable();
if (rtems_debugger_server_flag(RTEMS_DEBUGGER_FLAG_BREAK_WAITER)) {
rtems_debugger->flags &= ~RTEMS_DEBUGGER_FLAG_BREAK_WAITER;
r = rtems_debugger_thread_system_suspend();
if (rtems_debugger_verbose())
rtems_debugger_printf("rtems-db: break waiter\n");
rtems_debugger_server_events_signal();
if (rtems_debugger_verbose())
rtems_debugger_printf("rtems-db: break waiter: signalled\n");
}
if (r == 0) {
while (rtems_debugger_server_events_running()) { while (rtems_debugger_server_events_running()) {
rtems_debugger_server_events_wait(); rtems_debugger_server_events_wait();
if (rtems_debugger_verbose()) if (rtems_debugger_verbose())
@@ -1691,6 +1702,7 @@ rtems_debugger_events(rtems_task_argument arg)
if (r < 0) if (r < 0)
break; break;
} }
}
if (r < 0) if (r < 0)
rtems_debugger_printf("rtems-db: error in events\n"); rtems_debugger_printf("rtems-db: error in events\n");
@@ -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)
{ {
if (rtems_debugger_running()) {
rtems_debugger_lock(); rtems_debugger_lock();
rtems_debugger->remote_debug = state; rtems_debugger->remote_debug = state;
rtems_debugger_printf("rtems-db: remote-debug is %s\n", rtems_debugger_printf("rtems-db: remote-debug is %s\n",
rtems_debugger->remote_debug ? "on" : "off"); rtems_debugger->remote_debug ? "on" : "off");
rtems_debugger_unlock(); rtems_debugger_unlock();
} else {
rtems_debugger_printf("rtems-db: debug server not running\n");
}
return 0; return 0;
} }