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

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       |  2 +
 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          | 84 ++++++++++++++++++++++++-
 12 files changed, 374 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] 12+ messages in thread

* [PATCH 1/3] cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP
  2021-07-07 20:16 [PATCH 0/3] Add callback-like mechanism before/after ptrace stops Jan Kiszka
@ 2021-07-07 20:16 ` Jan Kiszka
  2021-07-08  7:44   ` Bezdeka, Florian
  2021-07-07 20:16 ` [PATCH 2/3] cobalt: Add ptrace debugging helper interface Jan Kiszka
  2021-07-07 20:16 ` [PATCH 3/3] testsuite/smokey/gdb: Add test cases for ptrace-based debugging helper Jan Kiszka
  2 siblings, 1 reply; 12+ messages in thread
From: Jan Kiszka @ 2021-07-07 20:16 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..618f965c2a 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;
+	int ignore = 0;
 	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 = 1;
 	}
 
 	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] 12+ messages in thread

* [PATCH 2/3] cobalt: Add ptrace debugging helper interface
  2021-07-07 20:16 [PATCH 0/3] Add callback-like mechanism before/after ptrace stops Jan Kiszka
  2021-07-07 20:16 ` [PATCH 1/3] cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP Jan Kiszka
@ 2021-07-07 20:16 ` Jan Kiszka
  2021-07-08  7:58   ` Florian Bezdeka
  2021-07-07 20:16 ` [PATCH 3/3] testsuite/smokey/gdb: Add test cases for ptrace-based debugging helper Jan Kiszka
  2 siblings, 1 reply; 12+ messages in thread
From: Jan Kiszka @ 2021-07-07 20:16 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   |  2 +
 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, 280 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..1fb4009d64 100644
--- a/include/cobalt/uapi/syscall.h
+++ b/include/cobalt/uapi/syscall.h
@@ -128,6 +128,8 @@
 #define sc_cobalt_clock_nanosleep64		105
 #define sc_cobalt_clock_getres64		106
 #define sc_cobalt_clock_adjtime64		107
+#define sc_cobalt_ptrace_helper_init		108
+#define sc_cobalt_ptrace_event_wait		109
 
 #define __NR_COBALT_SYSCALLS			128 /* Power of 2 */
 
diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index 1f059ad830..76514ec82f 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);
 
@@ -1043,6 +1072,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 279707a680..29294a8f60 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 618f965c2a..71aa669b88 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] 12+ messages in thread

* [PATCH 3/3] testsuite/smokey/gdb: Add test cases for ptrace-based debugging helper
  2021-07-07 20:16 [PATCH 0/3] Add callback-like mechanism before/after ptrace stops Jan Kiszka
  2021-07-07 20:16 ` [PATCH 1/3] cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP Jan Kiszka
  2021-07-07 20:16 ` [PATCH 2/3] cobalt: Add ptrace debugging helper interface Jan Kiszka
@ 2021-07-07 20:16 ` Jan Kiszka
  2 siblings, 0 replies; 12+ messages in thread
From: Jan Kiszka @ 2021-07-07 20:16 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 | 84 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 82 insertions(+), 2 deletions(-)

diff --git a/testsuite/smokey/gdb/gdb.c b/testsuite/smokey/gdb/gdb.c
index eabf75e6a2..ff97debd32 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,22 @@ 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");
+			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] 12+ messages in thread

* Re: [PATCH 1/3] cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP
  2021-07-07 20:16 ` [PATCH 1/3] cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP Jan Kiszka
@ 2021-07-08  7:44   ` Bezdeka, Florian
  2021-07-08  8:04     ` Jan Kiszka
  0 siblings, 1 reply; 12+ messages in thread
From: Bezdeka, Florian @ 2021-07-08  7:44 UTC (permalink / raw)
  To: xenomai, jan.kiszka

On Wed, 2021-07-07 at 22:16 +0200, Jan Kiszka via Xenomai wrote:
> 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..618f965c2a 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;
> +	int ignore = 0;

Why not bool?

>  	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 = 1;
>  	}
>  
> 
> 
> 
>  	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))


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

* Re: [PATCH 2/3] cobalt: Add ptrace debugging helper interface
  2021-07-07 20:16 ` [PATCH 2/3] cobalt: Add ptrace debugging helper interface Jan Kiszka
@ 2021-07-08  7:58   ` Florian Bezdeka
  2021-07-08  8:05     ` Jan Kiszka
  0 siblings, 1 reply; 12+ messages in thread
From: Florian Bezdeka @ 2021-07-08  7:58 UTC (permalink / raw)
  To: Jan Kiszka, xenomai, Song Chen

On 07.07.21 22:16, Jan Kiszka via Xenomai wrote:
> 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   |  2 +
>  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, 280 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..1fb4009d64 100644
> --- a/include/cobalt/uapi/syscall.h
> +++ b/include/cobalt/uapi/syscall.h
> @@ -128,6 +128,8 @@
>  #define sc_cobalt_clock_nanosleep64		105
>  #define sc_cobalt_clock_getres64		106
>  #define sc_cobalt_clock_adjtime64		107
> +#define sc_cobalt_ptrace_helper_init		108
> +#define sc_cobalt_ptrace_event_wait		109

Just a note that this affects the onoing Y2038 work. Song, we might have
to adjust the syscall numbers again (assuming that Jan is coming in earlier)

>  
>  #define __NR_COBALT_SYSCALLS			128 /* Power of 2 */
>  
> diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
> index 1f059ad830..76514ec82f 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);
>  
> @@ -1043,6 +1072,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 279707a680..29294a8f60 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 618f965c2a..71aa669b88 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;
> +}
> +
> +/** @} */
> 


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

* Re: [PATCH 1/3] cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP
  2021-07-08  7:44   ` Bezdeka, Florian
@ 2021-07-08  8:04     ` Jan Kiszka
  0 siblings, 0 replies; 12+ messages in thread
From: Jan Kiszka @ 2021-07-08  8:04 UTC (permalink / raw)
  To: Bezdeka, Florian (T RDA IOT SES-DE), xenomai

On 08.07.21 09:44, Bezdeka, Florian (T RDA IOT SES-DE) wrote:
> On Wed, 2021-07-07 at 22:16 +0200, Jan Kiszka via Xenomai wrote:
>> 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..618f965c2a 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;
>> +     int ignore = 0;
> 
> Why not bool?

Good point, will change.

Jan

> 
>>       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 = 1;
>>       }
>>
>>
>>
>>
>>       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))
> 


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


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

* Re: [PATCH 2/3] cobalt: Add ptrace debugging helper interface
  2021-07-08  7:58   ` Florian Bezdeka
@ 2021-07-08  8:05     ` Jan Kiszka
  2021-07-08  9:03       ` chensong_2000
  0 siblings, 1 reply; 12+ messages in thread
From: Jan Kiszka @ 2021-07-08  8:05 UTC (permalink / raw)
  To: Florian Bezdeka, xenomai, Song Chen

On 08.07.21 09:58, Florian Bezdeka wrote:
> On 07.07.21 22:16, Jan Kiszka via Xenomai wrote:
>> 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   |  2 +
>>  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, 280 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..1fb4009d64 100644
>> --- a/include/cobalt/uapi/syscall.h
>> +++ b/include/cobalt/uapi/syscall.h
>> @@ -128,6 +128,8 @@
>>  #define sc_cobalt_clock_nanosleep64		105
>>  #define sc_cobalt_clock_getres64		106
>>  #define sc_cobalt_clock_adjtime64		107
>> +#define sc_cobalt_ptrace_helper_init		108
>> +#define sc_cobalt_ptrace_event_wait		109
> 
> Just a note that this affects the onoing Y2038 work. Song, we might have
> to adjust the syscall numbers again (assuming that Jan is coming in earlier)
> 

If you already know how many additional calls you need, I can move my
reservation up and keep you block together.

Jan

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


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

* Re: [PATCH 2/3] cobalt: Add ptrace debugging helper interface
  2021-07-08  8:05     ` Jan Kiszka
@ 2021-07-08  9:03       ` chensong_2000
  2021-07-08  9:16         ` Bezdeka, Florian
  0 siblings, 1 reply; 12+ messages in thread
From: chensong_2000 @ 2021-07-08  9:03 UTC (permalink / raw)
  To: Jan Kiszka, Florian Bezdeka, xenomai



在 2021/7/8 下午4:05, Jan Kiszka 写道:
> On 08.07.21 09:58, Florian Bezdeka wrote:
>> On 07.07.21 22:16, Jan Kiszka via Xenomai wrote:
>>> 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   |  2 +
>>>   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, 280 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..1fb4009d64 100644
>>> --- a/include/cobalt/uapi/syscall.h
>>> +++ b/include/cobalt/uapi/syscall.h
>>> @@ -128,6 +128,8 @@
>>>   #define sc_cobalt_clock_nanosleep64		105
>>>   #define sc_cobalt_clock_getres64		106
>>>   #define sc_cobalt_clock_adjtime64		107
>>> +#define sc_cobalt_ptrace_helper_init		108
>>> +#define sc_cobalt_ptrace_event_wait		109
>>
>> Just a note that this affects the onoing Y2038 work. Song, we might have
>> to adjust the syscall numbers again (assuming that Jan is coming in earlier)
>>
> 
> If you already know how many additional calls you need, I can move my
> reservation up and keep you block together.

sc_cobalt_mutex_timedlock64
sc_cobalt_mq_timedsend64		
sc_cobalt_mq_timedreceive64		
sc_cobalt_sigtimedwait64		
sc_cobalt_thread_setschedparam_ex64
sc_cobalt_thread_getschedparam_ex64
cond_wait_prologue64
monitor_wait64
event_wait64
select64
recvmmsg64

those implementations are ongoing, please reserve, thanks.

@Florian, if you are available, please review 
mutex_timedlock64,mq_timedsend64 and mq_timedreceive64. thanks.

/Song

> 
> Jan
> 


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

* Re: [PATCH 2/3] cobalt: Add ptrace debugging helper interface
  2021-07-08  9:03       ` chensong_2000
@ 2021-07-08  9:16         ` Bezdeka, Florian
  2021-07-08 15:23           ` Jan Kiszka
  0 siblings, 1 reply; 12+ messages in thread
From: Bezdeka, Florian @ 2021-07-08  9:16 UTC (permalink / raw)
  To: xenomai, chensong_2000, jan.kiszka

On Thu, 2021-07-08 at 17:03 +0800, chensong_2000@189.cn wrote:
> 
> 在 2021/7/8 下午4:05, Jan Kiszka 写道:
> > On 08.07.21 09:58, Florian Bezdeka wrote:
> > > On 07.07.21 22:16, Jan Kiszka via Xenomai wrote:
> > > > 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   |  2 +
> > > >   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, 280 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..1fb4009d64 100644
> > > > --- a/include/cobalt/uapi/syscall.h
> > > > +++ b/include/cobalt/uapi/syscall.h
> > > > @@ -128,6 +128,8 @@
> > > >   #define sc_cobalt_clock_nanosleep64		105
> > > >   #define sc_cobalt_clock_getres64		106
> > > >   #define sc_cobalt_clock_adjtime64		107
> > > > +#define sc_cobalt_ptrace_helper_init		108
> > > > +#define sc_cobalt_ptrace_event_wait		109
> > > 
> > > Just a note that this affects the onoing Y2038 work. Song, we might have
> > > to adjust the syscall numbers again (assuming that Jan is coming in earlier)
> > > 
> > 
> > If you already know how many additional calls you need, I can move my
> > reservation up and keep you block together.
> 
> sc_cobalt_mutex_timedlock64 
> sc_cobalt_mq_timedsend64 		
> sc_cobalt_mq_timedreceive64		
> sc_cobalt_sigtimedwait64		
> sc_cobalt_thread_setschedparam_ex64 
> sc_cobalt_thread_getschedparam_ex64 
> cond_wait_prologue64 
> monitor_wait64  
> event_wait64 
> select64 
> recvmmsg64 
> 
> those implementations are ongoing, please reserve, thanks.

According to our list in [1] clock_adjtime64 is missing.

We should follow the order defined in [1] as well.

[1] https://gitlab.com/Xenomai/xenomai-hacker-space/-/wikis/y2038/Y2038_Affected_Syscalls

> 
> @Florian, if you are available, please review 
> mutex_timedlock64,mq_timedsend64 and mq_timedreceive64. thanks.

The next thing to review is mutex_timedlock64. I'm waiting for a series
containing the cleanup patch (POSIX "violation", time value being
optional) to come up. My understanding was that Jans questions have
been answered, so we would be able to continue.

> 
> /Song
> 
> > 
> > Jan
> > 


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

* Re: [PATCH 2/3] cobalt: Add ptrace debugging helper interface
  2021-07-08  9:16         ` Bezdeka, Florian
@ 2021-07-08 15:23           ` Jan Kiszka
  2021-07-08 15:24             ` Jan Kiszka
  0 siblings, 1 reply; 12+ messages in thread
From: Jan Kiszka @ 2021-07-08 15:23 UTC (permalink / raw)
  To: Bezdeka, Florian (T RDA IOT SES-DE), xenomai, chensong_2000

On 08.07.21 11:16, Bezdeka, Florian (T RDA IOT SES-DE) wrote:
> On Thu, 2021-07-08 at 17:03 +0800, chensong_2000@189.cn wrote:
>>
>> 在 2021/7/8 下午4:05, Jan Kiszka 写道:
>>> On 08.07.21 09:58, Florian Bezdeka wrote:
>>>> On 07.07.21 22:16, Jan Kiszka via Xenomai wrote:
>>>>> 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   |  2 +
>>>>>   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, 280 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..1fb4009d64 100644
>>>>> --- a/include/cobalt/uapi/syscall.h
>>>>> +++ b/include/cobalt/uapi/syscall.h
>>>>> @@ -128,6 +128,8 @@
>>>>>   #define sc_cobalt_clock_nanosleep64           105
>>>>>   #define sc_cobalt_clock_getres64              106
>>>>>   #define sc_cobalt_clock_adjtime64             107
>>>>> +#define sc_cobalt_ptrace_helper_init           108
>>>>> +#define sc_cobalt_ptrace_event_wait            109
>>>>
>>>> Just a note that this affects the onoing Y2038 work. Song, we might have
>>>> to adjust the syscall numbers again (assuming that Jan is coming in earlier)
>>>>
>>>
>>> If you already know how many additional calls you need, I can move my
>>> reservation up and keep you block together.
>>
>> sc_cobalt_mutex_timedlock64
>> sc_cobalt_mq_timedsend64
>> sc_cobalt_mq_timedreceive64
>> sc_cobalt_sigtimedwait64
>> sc_cobalt_thread_setschedparam_ex64
>> sc_cobalt_thread_getschedparam_ex64
>> cond_wait_prologue64
>> monitor_wait64
>> event_wait64
>> select64
>> recvmmsg64
>>
>> those implementations are ongoing, please reserve, thanks.
> 
> According to our list in [1] clock_adjtime64 is missing.
> 

That one is already upstream.

So I'm reserving now

/* 108-119 reserved for 64-bit time_t syscalls */

> We should follow the order defined in [1] as well.
> 
> [1] https://gitlab.com/Xenomai/xenomai-hacker-space/-/wikis/y2038/Y2038_Affected_Syscalls
> 

Well, then make sure to send a patch soon that reassigns IDs accordingly.

Jan

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


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

* Re: [PATCH 2/3] cobalt: Add ptrace debugging helper interface
  2021-07-08 15:23           ` Jan Kiszka
@ 2021-07-08 15:24             ` Jan Kiszka
  0 siblings, 0 replies; 12+ messages in thread
From: Jan Kiszka @ 2021-07-08 15:24 UTC (permalink / raw)
  To: Bezdeka, Florian (T RDA IOT SES-DE), xenomai, chensong_2000

On 08.07.21 17:23, Jan Kiszka wrote:
> On 08.07.21 11:16, Bezdeka, Florian (T RDA IOT SES-DE) wrote:
>> On Thu, 2021-07-08 at 17:03 +0800, chensong_2000@189.cn wrote:
>>>
>>> 在 2021/7/8 下午4:05, Jan Kiszka 写道:
>>>> On 08.07.21 09:58, Florian Bezdeka wrote:
>>>>> On 07.07.21 22:16, Jan Kiszka via Xenomai wrote:
>>>>>> 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   |  2 +
>>>>>>   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, 280 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..1fb4009d64 100644
>>>>>> --- a/include/cobalt/uapi/syscall.h
>>>>>> +++ b/include/cobalt/uapi/syscall.h
>>>>>> @@ -128,6 +128,8 @@
>>>>>>   #define sc_cobalt_clock_nanosleep64           105
>>>>>>   #define sc_cobalt_clock_getres64              106
>>>>>>   #define sc_cobalt_clock_adjtime64             107
>>>>>> +#define sc_cobalt_ptrace_helper_init           108
>>>>>> +#define sc_cobalt_ptrace_event_wait            109
>>>>>
>>>>> Just a note that this affects the onoing Y2038 work. Song, we might have
>>>>> to adjust the syscall numbers again (assuming that Jan is coming in earlier)
>>>>>
>>>>
>>>> If you already know how many additional calls you need, I can move my
>>>> reservation up and keep you block together.
>>>
>>> sc_cobalt_mutex_timedlock64
>>> sc_cobalt_mq_timedsend64
>>> sc_cobalt_mq_timedreceive64
>>> sc_cobalt_sigtimedwait64
>>> sc_cobalt_thread_setschedparam_ex64
>>> sc_cobalt_thread_getschedparam_ex64
>>> cond_wait_prologue64
>>> monitor_wait64
>>> event_wait64
>>> select64
>>> recvmmsg64
>>>
>>> those implementations are ongoing, please reserve, thanks.
>>
>> According to our list in [1] clock_adjtime64 is missing.
>>
> 
> That one is already upstream.
> 
> So I'm reserving now
> 
> /* 108-119 reserved for 64-bit time_t syscalls */
> 

Classic off-by-one: 108-108, i.e. 11 IDs.

Jan

>> We should follow the order defined in [1] as well.
>>
>> [1] https://gitlab.com/Xenomai/xenomai-hacker-space/-/wikis/y2038/Y2038_Affected_Syscalls
>>
> 
> Well, then make sure to send a patch soon that reassigns IDs accordingly.
> 
> Jan
> 

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


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

end of thread, other threads:[~2021-07-08 15:24 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-07 20:16 [PATCH 0/3] Add callback-like mechanism before/after ptrace stops Jan Kiszka
2021-07-07 20:16 ` [PATCH 1/3] cobalt/kernel: Introduce XNDBGCTRL to block SIGINT/SIGSTOP Jan Kiszka
2021-07-08  7:44   ` Bezdeka, Florian
2021-07-08  8:04     ` Jan Kiszka
2021-07-07 20:16 ` [PATCH 2/3] cobalt: Add ptrace debugging helper interface Jan Kiszka
2021-07-08  7:58   ` Florian Bezdeka
2021-07-08  8:05     ` Jan Kiszka
2021-07-08  9:03       ` chensong_2000
2021-07-08  9:16         ` Bezdeka, Florian
2021-07-08 15:23           ` Jan Kiszka
2021-07-08 15:24             ` Jan Kiszka
2021-07-07 20:16 ` [PATCH 3/3] testsuite/smokey/gdb: Add test cases for ptrace-based debugging helper Jan Kiszka

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.