All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops
@ 2021-07-08 20:47 Jan Kiszka
  2021-07-08 20:47 ` [PATCH v2 1/3] cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP Jan Kiszka
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Jan Kiszka @ 2021-07-08 20:47 UTC (permalink / raw)
  To: xenomai

Changes in v2:
 - use 'bool' in patch 1
 - reserve y2038 syscall range before adding new ones in patch 2
 - ignore SIG32 (cancellation) in patch 3 to avoid failing tests

This allows debugged real-time processes to execute crucial operations
right before and after being stopped by a debugger. Such operations can
include pausing physical devices and resuming them in an ordered manner
so that no harm is caused to the outer world while debugging takes place
and the real-time process can resume normally after the debugging
session. It may also involve informing cooperating processes about the
ongoing debug session.

The model chosen for this is dedicating a real-time thread to this task.
This has the advantage of isolating the thread a bit from the debugged
contexts and also avoids having to introduce any kind of asynchronous
signaling mechanism. The helper thread will register itself with the
core and then run a loop, waiting for the next stop or resume event. At
the point the helper receives such an event, all other real-time threads
in the process have been stopped or not yet resumed so that the helper
cannot interact with them nor should wait for resources they may have
locked. The helper thread may also migrate to secondary mode before
releasing control, usually only after/before all time-sensitive
operations are executed.

These patches have a very long (likely too long) internal history at
Siemens, thus have shown to be useful at least for one of our use cases.

Jan

Jan Kiszka (3):
  cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP
  cobalt: Add ptrace debugging helper interface
  testsuite/smokey/gdb: Add test cases for ptrace-based debugging helper

 include/cobalt/Makefile.am          |  1 +
 include/cobalt/ptrace.h             | 37 +++++++++++
 include/cobalt/uapi/Makefile.am     |  1 +
 include/cobalt/uapi/kernel/thread.h |  1 +
 include/cobalt/uapi/ptrace.h        | 24 +++++++
 include/cobalt/uapi/syscall.h       |  3 +
 kernel/cobalt/posix/process.c       | 34 +++++++++-
 kernel/cobalt/posix/process.h       |  5 ++
 kernel/cobalt/posix/syscall.c       | 98 ++++++++++++++++++++++++++++-
 lib/cobalt/Makefile.am              |  1 +
 lib/cobalt/ptrace.c                 | 91 +++++++++++++++++++++++++++
 testsuite/smokey/gdb/gdb.c          | 86 ++++++++++++++++++++++++-
 12 files changed, 377 insertions(+), 5 deletions(-)
 create mode 100644 include/cobalt/ptrace.h
 create mode 100644 include/cobalt/uapi/ptrace.h
 create mode 100644 lib/cobalt/ptrace.c

-- 
2.26.2



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 1/3] cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP
  2021-07-08 20:47 [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops Jan Kiszka
@ 2021-07-08 20:47 ` Jan Kiszka
  2021-07-08 20:47 ` [PATCH v2 2/3] cobalt: Add ptrace debugging helper interface Jan Kiszka
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2021-07-08 20:47 UTC (permalink / raw)
  To: xenomai

From: Jan Kiszka <jan.kiszka@siemens.com>

Setting XNDBGCTRL for a thread will prevent its migration to secondary
if only the debugging signals SIGINT or SIGSTOP are pending. Such
threads will still be able to trigger migration on other signals, such
as SIGDEBUG (watchdog), SIGCANCEL (SIGRTMIN) or synchronous SIGTRAP.

This is a building block for the debug helper feature.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/uapi/kernel/thread.h |  1 +
 kernel/cobalt/posix/syscall.c       | 12 +++++++++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/include/cobalt/uapi/kernel/thread.h b/include/cobalt/uapi/kernel/thread.h
index 664def08ef..74007ac0d6 100644
--- a/include/cobalt/uapi/kernel/thread.h
+++ b/include/cobalt/uapi/kernel/thread.h
@@ -51,6 +51,7 @@
 #define XNTRAPLB  0x00100000 /**< Trap lock break (i.e. may not sleep with sched lock) */
 #define XNDEBUG   0x00200000 /**< User-level debugging enabled */
 #define XNDBGSTOP 0x00400000 /**< Stopped for synchronous debugging */
+#define XNDBGCTRL 0x00800000 /**< Thread is protected against SIGSTOP/SIGINT */
 
 /** @} */
 
diff --git a/kernel/cobalt/posix/syscall.c b/kernel/cobalt/posix/syscall.c
index cd72b22d14..d46ff103de 100644
--- a/kernel/cobalt/posix/syscall.c
+++ b/kernel/cobalt/posix/syscall.c
@@ -86,6 +86,8 @@ static void prepare_for_signal(struct task_struct *p,
 			       struct pt_regs *regs,
 			       int sysflags)
 {
+	sigset_t pending;
+	bool ignore = false;
 	int notify = 0;
 	spl_t s;
 
@@ -100,13 +102,21 @@ static void prepare_for_signal(struct task_struct *p,
 			xnthread_clear_info(thread, XNBREAK);
 		}
 		xnthread_clear_info(thread, XNKICKED);
+	} else if (xnthread_test_state(thread, XNDBGCTRL)) {
+		/* only ignore thread-specific SIGSTOP/SIGINT */
+		pending = p->pending.signal;
+		sigdelset(&pending, SIGSTOP);
+		sigdelset(&pending, SIGINT);
+		if (sigisemptyset(&pending))
+			ignore = true;
 	}
 
 	xnlock_put_irqrestore(&nklock, s);
 
 	xnthread_test_cancel();
 
-	xnthread_relax(notify, SIGDEBUG_MIGRATE_SIGNAL);
+	if (!ignore)
+		xnthread_relax(notify, SIGDEBUG_MIGRATE_SIGNAL);
 }
 
 static COBALT_SYSCALL(migrate, current, (int domain))
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 2/3] cobalt: Add ptrace debugging helper interface
  2021-07-08 20:47 [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops Jan Kiszka
  2021-07-08 20:47 ` [PATCH v2 1/3] cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP Jan Kiszka
@ 2021-07-08 20:47 ` Jan Kiszka
  2021-07-08 20:47 ` [PATCH v2 3/3] testsuite/smokey/gdb: Add test cases for ptrace-based debugging helper Jan Kiszka
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2021-07-08 20:47 UTC (permalink / raw)
  To: xenomai

From: Jan Kiszka <jan.kiszka@siemens.com>

This introduces the concept of a debugging helper thread. It can
register itself with the cobalt core and then wait for ptrace stop and
resumption events. This can be used to bring the connected devices or
other parts of the system into a state that can tolerate the potentially
long interruption and also synchronize again with it to continue.

On stop events (breakpoints, debugger interceptions), the core will
ensure that the helper is run after all primary-mode threads were put on
hold and before the debugger will gain control over the whole process.
For that purpose, the helper will receive a notification when it was
pending on the corresponding event-wait syscall and will release the
process into debugging by invoking that syscall to wait for the
resumption event.

When the debugger resumes the whole process, the helper is resumed
first, right before all threads that will continue in primary mode are
released (threads in secondary mode may run earlier but will have to
wait when trying to enter primary mode). Again, the helper thread
decides when to continue by calling the event-wait system again, in
that case in order to wait for the next stop event.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/Makefile.am      |  1 +
 include/cobalt/ptrace.h         | 37 ++++++++++++++
 include/cobalt/uapi/Makefile.am |  1 +
 include/cobalt/uapi/ptrace.h    | 24 +++++++++
 include/cobalt/uapi/syscall.h   |  3 ++
 kernel/cobalt/posix/process.c   | 34 +++++++++++-
 kernel/cobalt/posix/process.h   |  5 ++
 kernel/cobalt/posix/syscall.c   | 86 +++++++++++++++++++++++++++++++
 lib/cobalt/Makefile.am          |  1 +
 lib/cobalt/ptrace.c             | 91 +++++++++++++++++++++++++++++++++
 10 files changed, 281 insertions(+), 2 deletions(-)
 create mode 100644 include/cobalt/ptrace.h
 create mode 100644 include/cobalt/uapi/ptrace.h
 create mode 100644 lib/cobalt/ptrace.c

diff --git a/include/cobalt/Makefile.am b/include/cobalt/Makefile.am
index 19e96112e8..e0b203193d 100644
--- a/include/cobalt/Makefile.am
+++ b/include/cobalt/Makefile.am
@@ -4,6 +4,7 @@ includesub_HEADERS =	\
 	fcntl.h		\
 	mqueue.h	\
 	pthread.h	\
+	ptrace.h	\
 	sched.h		\
 	semaphore.h	\
 	signal.h	\
diff --git a/include/cobalt/ptrace.h b/include/cobalt/ptrace.h
new file mode 100644
index 0000000000..f5bec56c9d
--- /dev/null
+++ b/include/cobalt/ptrace.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) Siemens AG, 2015-2021
+ *
+ * Authors:
+ *  Jan Kiszka <jan.kiszka@siemens.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA.
+ */
+#ifndef _COBALT_PTRACE_H
+#define _COBALT_PTRACE_H
+
+#include <cobalt/uapi/ptrace.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int cobalt_ptrace_helper_init(void);
+int cobalt_ptrace_event_wait(int event);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_COBALT_PTRACE_H */
diff --git a/include/cobalt/uapi/Makefile.am b/include/cobalt/uapi/Makefile.am
index d887213f8e..41076e23d9 100644
--- a/include/cobalt/uapi/Makefile.am
+++ b/include/cobalt/uapi/Makefile.am
@@ -6,6 +6,7 @@ includesub_HEADERS =	\
 	event.h		\
 	monitor.h	\
 	mutex.h		\
+	ptrace.h	\
 	sched.h		\
 	sem.h		\
 	signal.h	\
diff --git a/include/cobalt/uapi/ptrace.h b/include/cobalt/uapi/ptrace.h
new file mode 100644
index 0000000000..4e61d458c1
--- /dev/null
+++ b/include/cobalt/uapi/ptrace.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) Siemens AG, 2015-2021
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#ifndef _COBALT_UAPI_PTRACE_H
+#define _COBALT_UAPI_PTRACE_H
+
+#define COBALT_PTRACE_EVENT_STOP	0x1
+#define COBALT_PTRACE_EVENT_RESUME	0x2
+
+#endif /* !_COBALT_UAPI_PTRACE_H */
diff --git a/include/cobalt/uapi/syscall.h b/include/cobalt/uapi/syscall.h
index a2795a3644..8d10992284 100644
--- a/include/cobalt/uapi/syscall.h
+++ b/include/cobalt/uapi/syscall.h
@@ -128,6 +128,9 @@
 #define sc_cobalt_clock_nanosleep64		105
 #define sc_cobalt_clock_getres64		106
 #define sc_cobalt_clock_adjtime64		107
+/* 108-118 reserved for 64-bit time_t syscalls */
+#define sc_cobalt_ptrace_helper_init		119
+#define sc_cobalt_ptrace_event_wait		120
 
 #define __NR_COBALT_SYSCALLS			128 /* Power of 2 */
 
diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index 98b7df33fb..ad7def2f27 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -45,6 +45,7 @@
 #include <cobalt/kernel/ppd.h>
 #include <cobalt/kernel/vdso.h>
 #include <cobalt/kernel/thread.h>
+#include <cobalt/uapi/ptrace.h>
 #include <cobalt/uapi/signal.h>
 #include <cobalt/uapi/syscall.h>
 #include <pipeline/sched.h>
@@ -683,16 +684,25 @@ void cobalt_stop_debugged_process(struct xnthread *thread)
 	struct cobalt_process *process = process_from_thread(thread);
 	struct cobalt_thread *cth;
 
-	if (process->debugged_threads > 0)
+	if (process->stopped_for_ptrace)
 		return;
 
+	process->stopped_for_ptrace = true;
+
 	list_for_each_entry(cth, &process->thread_list, next) {
-		if (&cth->threadbase == thread)
+		if (&cth->threadbase == thread ||
+		    &cth->threadbase == process->ptrace_helper)
 			continue;
 
 		xnthread_suspend(&cth->threadbase, XNDBGSTOP, XN_INFINITE,
 				 XN_RELATIVE, NULL);
 	}
+
+	if (process->ptrace_helper) {
+		process->pending_ptrace_events |= COBALT_PTRACE_EVENT_STOP;
+		if (xnsynch_wakeup_one_sleeper(&process->ptrace_stop_event))
+			xnsched_run();
+	}
 }
 
 static void cobalt_resume_debugged_process(struct cobalt_process *process)
@@ -705,6 +715,8 @@ static void cobalt_resume_debugged_process(struct cobalt_process *process)
 		if (xnthread_test_state(&cth->threadbase, XNDBGSTOP))
 			xnthread_resume(&cth->threadbase, XNDBGSTOP);
 
+	process->stopped_for_ptrace = false;
+
 	xnsched_unlock();
 }
 
@@ -728,6 +740,17 @@ void cobalt_unregister_debugged_thread(struct xnthread *thread)
 {
 	struct cobalt_process *process = process_from_thread(thread);
 
+	if (process->ptrace_helper && process->debugged_threads == 1 &&
+	    !(process->pending_ptrace_events & COBALT_PTRACE_EVENT_RESUME)) {
+		process->pending_ptrace_events |= COBALT_PTRACE_EVENT_RESUME;
+		if (process->ptrace_helper != thread) {
+			xnthread_clear_state(thread, XNSSTEP);
+			xnthread_set_state(process->ptrace_helper, XNSSTEP);
+		}
+		xnthread_resume(process->ptrace_helper, XNDBGSTOP);
+		return;
+	}
+
 	process->debugged_threads--;
 	xnthread_clear_state(thread, XNSSTEP);
 
@@ -834,6 +857,7 @@ void cobalt_adjust_affinity(struct task_struct *task) /* nklocked, IRQs off */
 
 static void __handle_taskexit_event(struct task_struct *p)
 {
+	struct cobalt_process *process = cobalt_current_process();
 	struct cobalt_ppd *sys_ppd;
 	struct xnthread *thread;
 	spl_t s;
@@ -850,6 +874,11 @@ static void __handle_taskexit_event(struct task_struct *p)
 
 	xnlock_get_irqsave(&nklock, s);
 
+	if (process && process->ptrace_helper == thread) {
+		process->ptrace_helper = NULL;
+		process->pending_ptrace_events = 0;
+	}
+
 	if (xnthread_test_state(thread, XNSSTEP))
 		cobalt_unregister_debugged_thread(thread);
 
@@ -1057,6 +1086,7 @@ static void *cobalt_process_attach(void)
 	INIT_LIST_HEAD(&process->thread_list);
 	xntree_init(&process->usems);
 	bitmap_fill(process->timers_map, CONFIG_XENO_OPT_NRTIMERS);
+	xnsynch_init(&process->ptrace_stop_event, XNSYNCH_FIFO, NULL);
 	cobalt_set_process(process);
 
 	return process;
diff --git a/kernel/cobalt/posix/process.h b/kernel/cobalt/posix/process.h
index 46dff43b7a..c9bccdb361 100644
--- a/kernel/cobalt/posix/process.h
+++ b/kernel/cobalt/posix/process.h
@@ -22,6 +22,7 @@
 #include <linux/bitmap.h>
 #include <pipeline/thread.h>
 #include <cobalt/kernel/ppd.h>
+#include <cobalt/kernel/synch.h>
 
 #define NR_PERSONALITIES  4
 #if BITS_PER_LONG < NR_PERSONALITIES
@@ -55,6 +56,10 @@ struct cobalt_process {
 	void *priv[NR_PERSONALITIES];
 	int ufeatures;
 	unsigned int debugged_threads;
+	struct xnthread *ptrace_helper;
+	struct xnsynch ptrace_stop_event;
+	unsigned int pending_ptrace_events;
+	bool stopped_for_ptrace;
 };
 
 struct cobalt_resnode {
diff --git a/kernel/cobalt/posix/syscall.c b/kernel/cobalt/posix/syscall.c
index d46ff103de..ed1c215980 100644
--- a/kernel/cobalt/posix/syscall.c
+++ b/kernel/cobalt/posix/syscall.c
@@ -22,6 +22,7 @@
 #include <linux/kconfig.h>
 #include <linux/unistd.h>
 #include <cobalt/uapi/corectl.h>
+#include <cobalt/uapi/ptrace.h>
 #include <cobalt/kernel/tree.h>
 #include <cobalt/kernel/vdso.h>
 #include <cobalt/kernel/init.h>
@@ -287,6 +288,91 @@ static COBALT_SYSCALL(serialdbg, current,
 	return 0;
 }
 
+static COBALT_SYSCALL(ptrace_helper_init, current, (void))
+{
+	struct cobalt_process *process = cobalt_current_process();
+	struct xnthread *curr = xnthread_current();
+	int err = 0;
+	spl_t s;
+
+	if (curr == NULL || process == NULL)
+		return -EPERM;
+
+	xnlock_get_irqsave(&nklock, s);
+
+	if (!process->ptrace_helper)
+		process->ptrace_helper = curr;
+	else
+		err = -EBUSY;
+
+	xnlock_put_irqrestore(&nklock, s);
+
+	return err;
+}
+
+static COBALT_SYSCALL(ptrace_event_wait, primary, (int event))
+{
+	struct cobalt_process *process = cobalt_current_process();
+	struct xnthread *curr = xnthread_current();
+	int ret = 0;
+	spl_t s;
+
+	xnlock_get_irqsave(&nklock, s);
+
+	if (curr == NULL || process == NULL || process->ptrace_helper != curr) {
+		ret = -EPERM;
+		goto out;
+	}
+
+	if (event == COBALT_PTRACE_EVENT_STOP) {
+		xnthread_set_state(curr, XNDBGCTRL);
+
+		if (process->debugged_threads == 1)
+			cobalt_unregister_debugged_thread(curr);
+
+		if (process->pending_ptrace_events & COBALT_PTRACE_EVENT_STOP) {
+			process->pending_ptrace_events = 0;
+			goto out;
+		}
+
+		/* Now wait for the next debugging round. */
+		if (xnsynch_sleep_on(&process->ptrace_stop_event, XN_INFINITE,
+				     XN_RELATIVE) & XNBREAK)
+			ret = -ERESTARTSYS;
+		else
+			process->pending_ptrace_events = 0;
+	} else if (event == COBALT_PTRACE_EVENT_RESUME) {
+		xnthread_clear_state(curr, XNDBGCTRL);
+
+		if (process->pending_ptrace_events & COBALT_PTRACE_EVENT_RESUME)
+			goto out;
+
+		/*
+		 * Now wait for the end of the debugging round. If there is
+		 * already SIGSTOP pending, interrupt the suspension and relax
+		 * the helper thread on return from the syscall. The syscall
+		 * will be restarted when the thread resumes, then with
+		 * COBALT_PTRACE_EVENT_RESUME pending so that we will not block
+		 * again.
+		 */
+		if (signal_pending(current)) {
+			ret = -ERESTARTSYS;
+		} else {
+			xnthread_suspend(curr, XNDBGSTOP, XN_INFINITE, XN_RELATIVE,
+					NULL);
+			if (xnthread_test_info(curr, XNBREAK))
+				ret = -ERESTARTSYS;
+		}
+	} else {
+		ret = -EINVAL;
+	}
+
+out:
+	xnlock_put_irqrestore(&nklock, s);
+
+	return ret;
+}
+
 static void stringify_feature_set(unsigned long fset, char *buf, int size)
 {
 	unsigned long feature;
diff --git a/lib/cobalt/Makefile.am b/lib/cobalt/Makefile.am
index b3003cd957..3f9136e84c 100644
--- a/lib/cobalt/Makefile.am
+++ b/lib/cobalt/Makefile.am
@@ -24,6 +24,7 @@ libcobalt_la_SOURCES =		\
 	mutex.c			\
 	parse_vdso.c		\
 	printf.c		\
+	ptrace.c		\
 	rtdm.c			\
 	sched.c			\
 	select.c		\
diff --git a/lib/cobalt/ptrace.c b/lib/cobalt/ptrace.c
new file mode 100644
index 0000000000..f0c305b7b0
--- /dev/null
+++ b/lib/cobalt/ptrace.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) Siemens AG, 2015-2021
+ *
+ * Authors:
+ *  Jan Kiszka <jan.kiszka@siemens.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA.
+ */
+#include <pthread.h>
+#include <cobalt/ptrace.h>
+#include <asm/xenomai/syscall.h>
+
+/**
+ * @ingroup cobalt_api
+ * @defgroup cobalt_ptrace Debugging extension
+ *
+ * Cobalt process debugging extensions
+ *
+ *@{
+ */
+
+/**
+ * Register thread as ptrace helper
+ *
+ * Register the calling thread as ptrace debugging helper. Only one thread in
+ * a process can take over this role which will be in effect until the thread
+ * terminates.
+ *
+ * @retval 0 on success;
+ * @retval -1 with @a errno set if:
+ * - EBUSY, another thread is already registered.
+ * - EPERM, caller is not a Cobalt thread.
+ */
+int cobalt_ptrace_helper_init(void)
+{
+	int ret;
+
+	ret = XENOMAI_SYSCALL0(sc_cobalt_ptrace_helper_init);
+	if (ret < 0) {
+		errno = -ret;
+		return -1;
+	}
+
+	return ret;
+}
+
+/**
+ * Wait on the next ptrace helper event
+ *
+ * Block the caller until the next ptrace even for the helper arrives. The
+ * caller must have been registered as ptrace helper before.
+ *
+ * @param event type of event to wait for, either @a COBALT_PTRACE_EVENT_STOP
+ * or @a COBALT_PTRACE_EVENT_RESUME
+ *
+ * @retval 0 on success;
+ * @retval -1 with @a errno set if:
+ * - EINVAL, invalid @a event.
+ * - EPERM, caller is not a Cobalt thread.
+ */
+int cobalt_ptrace_event_wait(int event)
+{
+	int ret, oldtype;
+
+	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+	ret = XENOMAI_SYSCALL1(sc_cobalt_ptrace_event_wait, event);
+
+	pthread_setcanceltype(oldtype, NULL);
+
+	if (ret < 0) {
+		errno = -ret;
+		return -1;
+	}
+
+	return ret;
+}
+
+/** @} */
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 3/3] testsuite/smokey/gdb: Add test cases for ptrace-based debugging helper
  2021-07-08 20:47 [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops Jan Kiszka
  2021-07-08 20:47 ` [PATCH v2 1/3] cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP Jan Kiszka
  2021-07-08 20:47 ` [PATCH v2 2/3] cobalt: Add ptrace debugging helper interface Jan Kiszka
@ 2021-07-08 20:47 ` Jan Kiszka
  2021-07-12  9:45 ` [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops Jan Kiszka
  2021-07-19 10:08 ` Richard Weinberger
  4 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2021-07-08 20:47 UTC (permalink / raw)
  To: xenomai

From: Jan Kiszka <jan.kiszka@siemens.com>

Extend the gdb test with cases that stress the debugging helper thread.
We check if the helper is run on hitting a breakpoint as well as before
resuming the process afterwards.

This should be extended in the future by also testing error cases.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 testsuite/smokey/gdb/gdb.c | 86 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 84 insertions(+), 2 deletions(-)

diff --git a/testsuite/smokey/gdb/gdb.c b/testsuite/smokey/gdb/gdb.c
index eabf75e6a2..5e7f1c8991 100644
--- a/testsuite/smokey/gdb/gdb.c
+++ b/testsuite/smokey/gdb/gdb.c
@@ -18,6 +18,7 @@
 #include <semaphore.h>
 #include <sys/wait.h>
 #include <xeno_config.h>
+#include <cobalt/ptrace.h>
 #include <boilerplate/libc.h>
 #include <smokey/smokey.h>
 #include "lib/cobalt/current.h"
@@ -65,10 +66,12 @@ smokey_test_plugin(gdb,
 
 static int pipe_in[2], pipe_out[2];
 static volatile unsigned long long thread_loops, expected_loops;
+static volatile unsigned int stop_events, cont_events;
+static volatile int terminate, ptrace_helper_terminated;
 static volatile int primary_mode;
-static volatile int terminate;
 static int child_terminated;
-static sem_t kickoff_lo;
+static sem_t kickoff_lo, kickoff_helper;
+static pthread_t thread_ptrace_helper;
 
 static void handle_sigchld(int signum)
 {
@@ -184,9 +187,61 @@ static void *thread_hi_func(void *arg)
 	breakpoint_target();
 
 	/* 2nd bp: synchronous continue */
+	breakpoint_target();
+
+	err = sem_post(&kickoff_helper);
+	check_no_error("sem_post", err);
+
+	nanosleep(&ts, NULL);
+
+	/* 3rd bp: synchronous stop with ptrace helper in place */
 	expected_loops = thread_loops;
 	breakpoint_target();
+
+	/* 4th bp: synchronous continue with ptrace helper */
+	breakpoint_target();
+
+	/* 5th bp: terminate ptrace helper (and spinning thread) */
 	terminate = 1;
+	err = pthread_cancel(thread_ptrace_helper);
+	check_no_error("pthread_cancel", err);
+	err = pthread_join(thread_ptrace_helper, NULL);
+	check_no_error("pthread_join", err);
+	ptrace_helper_terminated = 1;
+	breakpoint_target();
+
+	return NULL;
+}
+
+static void *thread_ptrace_helper_func(void *arg)
+{
+	int err, event = COBALT_PTRACE_EVENT_STOP;
+
+	pthread_setname_np(pthread_self(), "pthelper");
+
+	err = sem_wait(&kickoff_helper);
+	check_no_error("sem_wait", err);
+
+	err = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+	check_no_error("pthread_setcanceltype", err);
+
+	err = cobalt_ptrace_helper_init();
+	check_no_error("cobalt_ptrace_helper_init", err);
+
+	while (1) {
+		err = cobalt_ptrace_event_wait(event);
+		check_no_error("cobalt_ptrace_event_wait", err);
+
+		if (event == COBALT_PTRACE_EVENT_STOP) {
+			stop_events++;
+			event = COBALT_PTRACE_EVENT_RESUME;
+		} else {
+			check("event is COBALT_PTRACE_EVENT_RESUME",
+			      event, COBALT_PTRACE_EVENT_RESUME);
+			cont_events++;
+			event = COBALT_PTRACE_EVENT_STOP;
+		}
+	}
 
 	return NULL;
 }
@@ -223,6 +278,8 @@ static int run_gdb(struct smokey_test *t, int argc, char *const argv[])
 
 		err = sem_init(&kickoff_lo, 0, 0);
 		check_no_error("sem_init", err);
+		err = sem_init(&kickoff_helper, 0, 0);
+		check_no_error("sem_init", err);
 
 		err = pthread_attr_init(&attr);
 		check_no_error("pthread_attr_init", err);
@@ -233,6 +290,13 @@ static int run_gdb(struct smokey_test *t, int argc, char *const argv[])
 		err = pthread_attr_setaffinity_np(&attr, sizeof(cpu_set), &cpu_set);
 		check_no_error("pthread_attr_setaffinity_np", err);
 
+		params.sched_priority = 3;
+		err = pthread_attr_setschedparam(&attr, &params);
+		check_no_error("pthread_attr_setschedparam", err);
+		err = pthread_create(&thread_ptrace_helper, &attr,
+				     thread_ptrace_helper_func, NULL);
+		check_no_error("pthread_create", err);
+
 		params.sched_priority = 2;
 		err = pthread_attr_setschedparam(&attr, &params);
 		check_no_error("pthread_attr_setschedparam", err);
@@ -293,6 +357,24 @@ static int run_gdb(struct smokey_test *t, int argc, char *const argv[])
 
 			smokey_trace("synchronous continue");
 			eval_expression("thread_loops==expected_loops", "1");
+			send_command("c\n", 1);
+
+			smokey_trace("stop with event");
+			eval_expression("thread_loops==expected_loops", "1");
+			eval_expression("stop_events", "1");
+			eval_expression("cont_events", "0");
+			send_command("c\n", 1);
+
+			smokey_trace("continue with event");
+			eval_expression("thread_loops==expected_loops", "1");
+			eval_expression("stop_events", "2");
+			eval_expression("cont_events", "1");
+			/* SIG32 is used by glibc to cancel threads */
+			send_command("handle SIG32 noprint\n", 1);
+			send_command("c\n", 1);
+
+			smokey_trace("terminate ptrace helper");
+			eval_expression("ptrace_helper_terminated", "1");
 
 			send_command("q\n", 0);
 			pause();
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops
  2021-07-08 20:47 [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops Jan Kiszka
                   ` (2 preceding siblings ...)
  2021-07-08 20:47 ` [PATCH v2 3/3] testsuite/smokey/gdb: Add test cases for ptrace-based debugging helper Jan Kiszka
@ 2021-07-12  9:45 ` Jan Kiszka
  2021-07-19 10:08 ` Richard Weinberger
  4 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2021-07-12  9:45 UTC (permalink / raw)
  To: xenomai

On 08.07.21 22:47, Jan Kiszka via Xenomai wrote:
> Changes in v2:
>  - use 'bool' in patch 1
>  - reserve y2038 syscall range before adding new ones in patch 2
>  - ignore SIG32 (cancellation) in patch 3 to avoid failing tests
> 
> This allows debugged real-time processes to execute crucial operations
> right before and after being stopped by a debugger. Such operations can
> include pausing physical devices and resuming them in an ordered manner
> so that no harm is caused to the outer world while debugging takes place
> and the real-time process can resume normally after the debugging
> session. It may also involve informing cooperating processes about the
> ongoing debug session.
> 
> The model chosen for this is dedicating a real-time thread to this task.
> This has the advantage of isolating the thread a bit from the debugged
> contexts and also avoids having to introduce any kind of asynchronous
> signaling mechanism. The helper thread will register itself with the
> core and then run a loop, waiting for the next stop or resume event. At
> the point the helper receives such an event, all other real-time threads
> in the process have been stopped or not yet resumed so that the helper
> cannot interact with them nor should wait for resources they may have
> locked. The helper thread may also migrate to secondary mode before
> releasing control, usually only after/before all time-sensitive
> operations are executed.
> 
> These patches have a very long (likely too long) internal history at
> Siemens, thus have shown to be useful at least for one of our use cases.
> 
> Jan
> 
> Jan Kiszka (3):
>   cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP
>   cobalt: Add ptrace debugging helper interface
>   testsuite/smokey/gdb: Add test cases for ptrace-based debugging helper
> 
>  include/cobalt/Makefile.am          |  1 +
>  include/cobalt/ptrace.h             | 37 +++++++++++
>  include/cobalt/uapi/Makefile.am     |  1 +
>  include/cobalt/uapi/kernel/thread.h |  1 +
>  include/cobalt/uapi/ptrace.h        | 24 +++++++
>  include/cobalt/uapi/syscall.h       |  3 +
>  kernel/cobalt/posix/process.c       | 34 +++++++++-
>  kernel/cobalt/posix/process.h       |  5 ++
>  kernel/cobalt/posix/syscall.c       | 98 ++++++++++++++++++++++++++++-
>  lib/cobalt/Makefile.am              |  1 +
>  lib/cobalt/ptrace.c                 | 91 +++++++++++++++++++++++++++
>  testsuite/smokey/gdb/gdb.c          | 86 ++++++++++++++++++++++++-
>  12 files changed, 377 insertions(+), 5 deletions(-)
>  create mode 100644 include/cobalt/ptrace.h
>  create mode 100644 include/cobalt/uapi/ptrace.h
>  create mode 100644 lib/cobalt/ptrace.c
> 

32-bit ARM is still showing issues of this series, possibly generic
ones. Will continue to debug this today and otherwise pull things out of
next again.

Jan

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops
  2021-07-08 20:47 [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops Jan Kiszka
                   ` (3 preceding siblings ...)
  2021-07-12  9:45 ` [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops Jan Kiszka
@ 2021-07-19 10:08 ` Richard Weinberger
  2021-07-19 14:42   ` Jan Kiszka
  4 siblings, 1 reply; 15+ messages in thread
From: Richard Weinberger @ 2021-07-19 10:08 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai, David Oberhollenzer

On Thu, Jul 8, 2021 at 10:48 PM Jan Kiszka via Xenomai
<xenomai@xenomai.org> wrote:
> The model chosen for this is dedicating a real-time thread to this task.
> This has the advantage of isolating the thread a bit from the debugged
> contexts and also avoids having to introduce any kind of asynchronous
> signaling mechanism. The helper thread will register itself with the
> core and then run a loop, waiting for the next stop or resume event. At
> the point the helper receives such an event, all other real-time threads
> in the process have been stopped or not yet resumed so that the helper
> cannot interact with them nor should wait for resources they may have
> locked. The helper thread may also migrate to secondary mode before
> releasing control, usually only after/before all time-sensitive
> operations are executed.
>
> These patches have a very long (likely too long) internal history at
> Siemens, thus have shown to be useful at least for one of our use cases.

We have a similar but still rather different set of use cases.
A Xenomai 2 based system David and I working on carries a in house
patch to deliver
exceptions to userspace in the primary domain. The current patch implements
a signal alike interface. So userspace can register a hard real-time
handler for e.g. SIGFPE or SIGTRAP.
If a real-time task triggers an exception (e.g. division by zero,
hitting a break-point exception) this
exception is translated to a signal and delivered to userspace without switching
to the secondary domain.

The monitor thread approach should work too, I guess.
But the main difference is that the application I have in mind needs a
notification for exceptions,
plus machine state. This is why the signal model was chosen. Just like
on the Linux side
the real-time thread has access to mcontext to figure why the
exception happened, etc..

Let me outline two use cases.
1. FPU exception handling:
The application we work on is more a runtime than an application, it
runs programs that assume
specific behavior regarding integer and floating point operations.
These program have been developed for other operating systems and must
not break on
Linux/Xenomai.
For example they assume that a division by zero does not trap but results in 0.
So the runtime handles floating point exceptions, looks at the machine
state, decodes the current
operation and fixes the result.
Like it or not, we have to do this to keep binary compatibly.
Rebuilding these  programs
is not possible.

2. Break point handling:
The runtime allows instrumenting of programs it executes. A system
operator can mark code paths
to see how often they are executed. So the runtime installs a break
point instruction at the desired
place and handles the breakpoint exception in the primary domain where
just a counter
is incremented.
Although this slows down execution and hurts the system response time
it is still fast enough
to satisfy our real-time requirements.
On the other hand switching to the secondary domain is far too expensive.

Maybe we can combine both approaches? We'll happily port the current
patch to Xenomai 3.1
and give the monitor thread approach a try.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops
  2021-07-19 10:08 ` Richard Weinberger
@ 2021-07-19 14:42   ` Jan Kiszka
  2021-07-20  7:57     ` Richard Weinberger
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Kiszka @ 2021-07-19 14:42 UTC (permalink / raw)
  To: Richard Weinberger; +Cc: Xenomai, David Oberhollenzer

On 19.07.21 12:08, Richard Weinberger wrote:
> On Thu, Jul 8, 2021 at 10:48 PM Jan Kiszka via Xenomai
> <xenomai@xenomai.org> wrote:
>> The model chosen for this is dedicating a real-time thread to this task.
>> This has the advantage of isolating the thread a bit from the debugged
>> contexts and also avoids having to introduce any kind of asynchronous
>> signaling mechanism. The helper thread will register itself with the
>> core and then run a loop, waiting for the next stop or resume event. At
>> the point the helper receives such an event, all other real-time threads
>> in the process have been stopped or not yet resumed so that the helper
>> cannot interact with them nor should wait for resources they may have
>> locked. The helper thread may also migrate to secondary mode before
>> releasing control, usually only after/before all time-sensitive
>> operations are executed.
>>
>> These patches have a very long (likely too long) internal history at
>> Siemens, thus have shown to be useful at least for one of our use cases.
> 
> We have a similar but still rather different set of use cases.
> A Xenomai 2 based system David and I working on carries a in house
> patch to deliver
> exceptions to userspace in the primary domain. The current patch implements
> a signal alike interface. So userspace can register a hard real-time
> handler for e.g. SIGFPE or SIGTRAP.
> If a real-time task triggers an exception (e.g. division by zero,
> hitting a break-point exception) this
> exception is translated to a signal and delivered to userspace without switching
> to the secondary domain.
> 
> The monitor thread approach should work too, I guess.
> But the main difference is that the application I have in mind needs a
> notification for exceptions,
> plus machine state. This is why the signal model was chosen. Just like
> on the Linux side
> the real-time thread has access to mcontext to figure why the
> exception happened, etc..
> 
> Let me outline two use cases.
> 1. FPU exception handling:
> The application we work on is more a runtime than an application, it
> runs programs that assume
> specific behavior regarding integer and floating point operations.
> These program have been developed for other operating systems and must
> not break on
> Linux/Xenomai.
> For example they assume that a division by zero does not trap but results in 0.
> So the runtime handles floating point exceptions, looks at the machine
> state, decodes the current
> operation and fixes the result.
> Like it or not, we have to do this to keep binary compatibly.
> Rebuilding these  programs
> is not possible.

We have kind of a similar case in our backlog. The application expects
to handle certain FPU-related faults gracefully, i.e. without falling
out of RT with the causing thread, using a context update to bring it on
the road again.

We modeled that case on top of the debug monitor thread, waking it up
also on such faults and giving it a chance to remotely fix up the
triggering thread.

> 
> 2. Break point handling:
> The runtime allows instrumenting of programs it executes. A system
> operator can mark code paths
> to see how often they are executed. So the runtime installs a break
> point instruction at the desired
> place and handles the breakpoint exception in the primary domain where
> just a counter
> is incremented.
> Although this slows down execution and hurts the system response time
> it is still fast enough
> to satisfy our real-time requirements.
> On the other hand switching to the secondary domain is far too expensive.

But this is not debugging, this is UPROBES / UPROBE_EVENTS, no? Maybe
better make that work with oob if it does not yet.

> 
> Maybe we can combine both approaches? We'll happily port the current
> patch to Xenomai 3.1
> and give the monitor thread approach a try.
> 

I'd like to see how you implemented that signal-like context switching
in your approach. That is where I shied away from, rather using a thread
switch plus a (not too nice, granted) mcontext get/set for other threads.

My current understanding is that a real-time domain signal mechanism
will require changes in the pipeline patch underneath, thus first of all
needs to be sold to the dovetail infrastructure (and then we can discuss
if we backport that to ipipe anymore).

That said, I currently have a problem without remote fix-up approach as
well: I-pipe allowed Xenomai to declare a fault resolved, dovetail so
far always migrates the causing thread. If we would go that way, we
would also need a bit of dovetail changes. For that reason, I started to
question the remaining use cases for these self fix-ups internally
again, but I cannot tell yet how successful that will be.

Jan

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops
  2021-07-19 14:42   ` Jan Kiszka
@ 2021-07-20  7:57     ` Richard Weinberger
  2021-07-20  9:27       ` Jan Kiszka
  0 siblings, 1 reply; 15+ messages in thread
From: Richard Weinberger @ 2021-07-20  7:57 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai, David Oberhollenzer

On Mon, Jul 19, 2021 at 4:42 PM Jan Kiszka <jan.kiszka@siemens.com> wrote:
> We have kind of a similar case in our backlog. The application expects
> to handle certain FPU-related faults gracefully, i.e. without falling
> out of RT with the causing thread, using a context update to bring it on
> the road again.
>
> We modeled that case on top of the debug monitor thread, waking it up
> also on such faults and giving it a chance to remotely fix up the
> triggering thread.

Yeah, sounds related and I think useful for our case too.

> >
> > 2. Break point handling:
> > The runtime allows instrumenting of programs it executes. A system
> > operator can mark code paths
> > to see how often they are executed. So the runtime installs a break
> > point instruction at the desired
> > place and handles the breakpoint exception in the primary domain where
> > just a counter
> > is incremented.
> > Although this slows down execution and hurts the system response time
> > it is still fast enough
> > to satisfy our real-time requirements.
> > On the other hand switching to the secondary domain is far too expensive.
>
> But this is not debugging, this is UPROBES / UPROBE_EVENTS, no? Maybe
> better make that work with oob if it does not yet.

I don't disagree that uprobes might help but the whole point of our patch
is exception delivery to userspace. How userspace uses the exception is
not set in stone.
For example, the application itself is modifying the code and places
breakpoint instructions.
Another obstacle is that the application that runs on top of the
Xenomai based framework
is not a regular Linux application, it does not even follow the
calling convention, I bet this
makes things with uprobes not easier.

>
> >
> > Maybe we can combine both approaches? We'll happily port the current
> > patch to Xenomai 3.1
> > and give the monitor thread approach a try.
> >
>
> I'd like to see how you implemented that signal-like context switching
> in your approach. That is where I shied away from, rather using a thread
> switch plus a (not too nice, granted) mcontext get/set for other threads.

The key is ipipe_trap_hook().
__ipipe_notify_trap() passes a struct pt_regs of the trapping task to
ipipe_trap_hook(). In ipipe_trap_hook() a signal frame is placed on
the stack and
program counter, stack pointer, etc. in pt_regs are set accordingly.
After ipipe_trap_hook() returns, the entry logic in arch/arm/ or
arch/x86/ will restore
from the modified pt_regs and the trapping task executes the signal handler.

> My current understanding is that a real-time domain signal mechanism
> will require changes in the pipeline patch underneath, thus first of all
> needs to be sold to the dovetail infrastructure (and then we can discuss
> if we backport that to ipipe anymore).

I'm pretty sure our approach has issues but so far no changes to ipipe
are needed.

-- 
Thanks,
//richard


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops
  2021-07-20  7:57     ` Richard Weinberger
@ 2021-07-20  9:27       ` Jan Kiszka
  2021-07-20  9:33         ` Richard Weinberger
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Kiszka @ 2021-07-20  9:27 UTC (permalink / raw)
  To: Richard Weinberger; +Cc: Xenomai, David Oberhollenzer

On 20.07.21 09:57, Richard Weinberger wrote:
> On Mon, Jul 19, 2021 at 4:42 PM Jan Kiszka <jan.kiszka@siemens.com> wrote:
>> We have kind of a similar case in our backlog. The application expects
>> to handle certain FPU-related faults gracefully, i.e. without falling
>> out of RT with the causing thread, using a context update to bring it on
>> the road again.
>>
>> We modeled that case on top of the debug monitor thread, waking it up
>> also on such faults and giving it a chance to remotely fix up the
>> triggering thread.
> 
> Yeah, sounds related and I think useful for our case too.
> 
>>>
>>> 2. Break point handling:
>>> The runtime allows instrumenting of programs it executes. A system
>>> operator can mark code paths
>>> to see how often they are executed. So the runtime installs a break
>>> point instruction at the desired
>>> place and handles the breakpoint exception in the primary domain where
>>> just a counter
>>> is incremented.
>>> Although this slows down execution and hurts the system response time
>>> it is still fast enough
>>> to satisfy our real-time requirements.
>>> On the other hand switching to the secondary domain is far too expensive.
>>
>> But this is not debugging, this is UPROBES / UPROBE_EVENTS, no? Maybe
>> better make that work with oob if it does not yet.
> 
> I don't disagree that uprobes might help but the whole point of our patch
> is exception delivery to userspace. How userspace uses the exception is
> not set in stone.
> For example, the application itself is modifying the code and places
> breakpoint instructions.
> Another obstacle is that the application that runs on top of the
> Xenomai based framework
> is not a regular Linux application, it does not even follow the
> calling convention, I bet this
> makes things with uprobes not easier.
> 
>>
>>>
>>> Maybe we can combine both approaches? We'll happily port the current
>>> patch to Xenomai 3.1
>>> and give the monitor thread approach a try.
>>>
>>
>> I'd like to see how you implemented that signal-like context switching
>> in your approach. That is where I shied away from, rather using a thread
>> switch plus a (not too nice, granted) mcontext get/set for other threads.
> 
> The key is ipipe_trap_hook().
> __ipipe_notify_trap() passes a struct pt_regs of the trapping task to
> ipipe_trap_hook(). In ipipe_trap_hook() a signal frame is placed on
> the stack and
> program counter, stack pointer, etc. in pt_regs are set accordingly.
> After ipipe_trap_hook() returns, the entry logic in arch/arm/ or
> arch/x86/ will restore
> from the modified pt_regs and the trapping task executes the signal handler.
> 
>> My current understanding is that a real-time domain signal mechanism
>> will require changes in the pipeline patch underneath, thus first of all
>> needs to be sold to the dovetail infrastructure (and then we can discuss
>> if we backport that to ipipe anymore).
> 
> I'm pretty sure our approach has issues but so far no changes to ipipe
> are needed.
> 

Then look at dovetail - ipipe will vanish. I'm pretty sure now your
approach faces the same issue like we do /wrt not delivering fixed-up
faults.

If that is the case, we should first of all ensure that the foundation
is provided by the pipeline. Then we can sort out the API model and
implementation details at Xenomai-level.

Jan

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops
  2021-07-20  9:27       ` Jan Kiszka
@ 2021-07-20  9:33         ` Richard Weinberger
  2021-07-20 10:53           ` Jan Kiszka
  0 siblings, 1 reply; 15+ messages in thread
From: Richard Weinberger @ 2021-07-20  9:33 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai, David Oberhollenzer

On Tue, Jul 20, 2021 at 11:27 AM Jan Kiszka <jan.kiszka@siemens.com> wrote:
> Then look at dovetail - ipipe will vanish. I'm pretty sure now your
> approach faces the same issue like we do /wrt not delivering fixed-up
> faults.
>
> If that is the case, we should first of all ensure that the foundation
> is provided by the pipeline. Then we can sort out the API model and
> implementation details at Xenomai-level.

I've heard that with dovetail Xenomai no longer sees exceptions.
So this is a set in stone concept?

-- 
Thanks,
//richard


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops
  2021-07-20  9:33         ` Richard Weinberger
@ 2021-07-20 10:53           ` Jan Kiszka
  2021-07-20 11:17             ` Richard Weinberger
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Kiszka @ 2021-07-20 10:53 UTC (permalink / raw)
  To: Richard Weinberger; +Cc: Xenomai, David Oberhollenzer

On 20.07.21 11:33, Richard Weinberger wrote:
> On Tue, Jul 20, 2021 at 11:27 AM Jan Kiszka <jan.kiszka@siemens.com> wrote:
>> Then look at dovetail - ipipe will vanish. I'm pretty sure now your
>> approach faces the same issue like we do /wrt not delivering fixed-up
>> faults.
>>
>> If that is the case, we should first of all ensure that the foundation
>> is provided by the pipeline. Then we can sort out the API model and
>> implementation details at Xenomai-level.
> 
> I've heard that with dovetail Xenomai no longer sees exceptions.
> So this is a set in stone concept?

Xenomai can no longer declare exceptions resolved. It still sees them.

If we come up with a reasonable use case, I can't imagine that this is
set in stone.

Jan

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops
  2021-07-20 10:53           ` Jan Kiszka
@ 2021-07-20 11:17             ` Richard Weinberger
  2021-07-20 13:56               ` Philippe Gerum
  0 siblings, 1 reply; 15+ messages in thread
From: Richard Weinberger @ 2021-07-20 11:17 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai, David Oberhollenzer

On Tue, Jul 20, 2021 at 12:53 PM Jan Kiszka <jan.kiszka@siemens.com> wrote:
> > I've heard that with dovetail Xenomai no longer sees exceptions.
> > So this is a set in stone concept?
>
> Xenomai can no longer declare exceptions resolved. It still sees them.

Understood.

> If we come up with a reasonable use case, I can't imagine that this is
> set in stone.

I can understand that dovetail doesn't want to offer something super generic
as ipipe_trap_hook().
But maybe it can offer enough to implement signal delivery for exceptions?

The signal approach also allows us to use the very same signal
handlers in userspace
for realtime as provided by Xenomai and PREEMPT_RT.

-- 
Thanks,
//richard


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops
  2021-07-20 11:17             ` Richard Weinberger
@ 2021-07-20 13:56               ` Philippe Gerum
  2021-07-20 14:08                 ` Philippe Gerum
  2021-07-20 19:22                 ` Richard Weinberger
  0 siblings, 2 replies; 15+ messages in thread
From: Philippe Gerum @ 2021-07-20 13:56 UTC (permalink / raw)
  To: Richard Weinberger; +Cc: Jan Kiszka, xenomai


Richard Weinberger via Xenomai <xenomai@xenomai.org> writes:

> On Tue, Jul 20, 2021 at 12:53 PM Jan Kiszka <jan.kiszka@siemens.com> wrote:
>> > I've heard that with dovetail Xenomai no longer sees exceptions.
>> > So this is a set in stone concept?
>>
>> Xenomai can no longer declare exceptions resolved. It still sees them.
>
> Understood.
>
>> If we come up with a reasonable use case, I can't imagine that this is
>> set in stone.
>
> I can understand that dovetail doesn't want to offer something super generic
> as ipipe_trap_hook().

Just like the I-pipe, Dovetail implements a way to tell the companion
core that "something happened", including a fault for the current task,
by calling handlers with weak bindings the core can
override. For faults, this would be oob_trap_notify().

> But maybe it can offer enough to implement signal delivery for exceptions?
>
> The signal approach also allows us to use the very same signal
> handlers in userspace
> for realtime as provided by Xenomai and PREEMPT_RT.

You may want to post a proposal of such a feature for a recent Dovetail
release, so that we can discuss it, and figure out whether it can be
easily maintained for all the supported architectures in the long
run. This is the key issue to me.

-- 
Philippe.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops
  2021-07-20 13:56               ` Philippe Gerum
@ 2021-07-20 14:08                 ` Philippe Gerum
  2021-07-20 19:22                 ` Richard Weinberger
  1 sibling, 0 replies; 15+ messages in thread
From: Philippe Gerum @ 2021-07-20 14:08 UTC (permalink / raw)
  To: Richard Weinberger; +Cc: Jan Kiszka, xenomai


Philippe Gerum <rpm@xenomai.org> writes:

> Richard Weinberger via Xenomai <xenomai@xenomai.org> writes:
>
>> On Tue, Jul 20, 2021 at 12:53 PM Jan Kiszka <jan.kiszka@siemens.com> wrote:
>>> > I've heard that with dovetail Xenomai no longer sees exceptions.
>>> > So this is a set in stone concept?
>>>
>>> Xenomai can no longer declare exceptions resolved. It still sees them.
>>
>> Understood.
>>
>>> If we come up with a reasonable use case, I can't imagine that this is
>>> set in stone.
>>
>> I can understand that dovetail doesn't want to offer something super generic
>> as ipipe_trap_hook().
>
> Just like the I-pipe, Dovetail implements a way to tell the companion
> core that "something happened", including a fault for the current task,
> by calling handlers with weak bindings the core can
> override. For faults, this would be oob_trap_notify().

oob_trap_notify() is a Dovetail service calling the following weak hooks
which should be provided by the core actually: handle_oob_trap_entry()
then handle_oob_trap_exit().

-- 
Philippe.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops
  2021-07-20 13:56               ` Philippe Gerum
  2021-07-20 14:08                 ` Philippe Gerum
@ 2021-07-20 19:22                 ` Richard Weinberger
  1 sibling, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2021-07-20 19:22 UTC (permalink / raw)
  To: Philippe Gerum; +Cc: Jan Kiszka, Xenomai

On Tue, Jul 20, 2021 at 3:56 PM Philippe Gerum <rpm@xenomai.org> wrote:

> > But maybe it can offer enough to implement signal delivery for exceptions?
> >
> > The signal approach also allows us to use the very same signal
> > handlers in userspace
> > for realtime as provided by Xenomai and PREEMPT_RT.
>
> You may want to post a proposal of such a feature for a recent Dovetail
> release, so that we can discuss it, and figure out whether it can be
> easily maintained for all the supported architectures in the long
> run. This is the key issue to me.

True. Time to explore dovetail in more detail. :-)

-- 
Thanks,
//richard


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2021-07-20 19:22 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-08 20:47 [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops Jan Kiszka
2021-07-08 20:47 ` [PATCH v2 1/3] cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP Jan Kiszka
2021-07-08 20:47 ` [PATCH v2 2/3] cobalt: Add ptrace debugging helper interface Jan Kiszka
2021-07-08 20:47 ` [PATCH v2 3/3] testsuite/smokey/gdb: Add test cases for ptrace-based debugging helper Jan Kiszka
2021-07-12  9:45 ` [PATCH v2 0/3] Add callback-like mechanism before/after ptrace stops Jan Kiszka
2021-07-19 10:08 ` Richard Weinberger
2021-07-19 14:42   ` Jan Kiszka
2021-07-20  7:57     ` Richard Weinberger
2021-07-20  9:27       ` Jan Kiszka
2021-07-20  9:33         ` Richard Weinberger
2021-07-20 10:53           ` Jan Kiszka
2021-07-20 11:17             ` Richard Weinberger
2021-07-20 13:56               ` Philippe Gerum
2021-07-20 14:08                 ` Philippe Gerum
2021-07-20 19:22                 ` Richard Weinberger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.