[PATCH v2 7/7] Implement testing framework for pidns

Ákos Uzonyi uzonyi.akos at gmail.com
Tue Jul 21 21:19:25 UTC 2020


* tests/pidns.c: New file.
* tests/pidns.h: New file.
* tests/Makefile.am (libtests_a_SOURCES): Add pidns.c.
* tests/init.sh (test_pidns, test_pidns_run_strace): New functions.
---
 tests/.gitignore                              |  31 ++++
 tests/Makefile.am                             |  37 ++++
 tests/fcntl--pidns-translation.c              |   2 +
 tests/fcntl-common.c                          |  88 +++++++---
 tests/fcntl.c                                 |   1 +
 tests/fcntl64--pidns-translation.c            |   2 +
 tests/fcntl64.c                               |   3 +
 tests/fork--pidns-translation.awk             |   8 +
 tests/fork--pidns-translation.c               |  62 +++++++
 tests/fork--pidns-translation.test            |  14 ++
 tests/gen_tests.in                            |  28 +++
 tests/getpgrp--pidns-translation.c            |   2 +
 tests/getpgrp.c                               |  10 +-
 tests/getpid--pidns-translation.c             |   2 +
 tests/getpid.c                                |  10 +-
 tests/getsid--pidns-translation.c             |   2 +
 tests/getsid.c                                |  11 +-
 tests/gettid--pidns-translation.c             |   2 +
 tests/gettid.c                                |  10 +-
 tests/init.sh                                 |  30 ++++
 tests/ioctl_block--pidns-translation.c        |   2 +
 tests/ioctl_block--pidns-translation.test     |  20 +++
 tests/ioctl_block.c                           |  26 ++-
 tests/ioprio--pidns-translation.c             |   2 +
 tests/ioprio.c                                |  56 ++++--
 tests/kcmp-yY.c                               |   2 +
 tests/kcmp.c                                  |  13 +-
 tests/kill--pidns-translation.c               |   2 +
 tests/kill.c                                  |  14 +-
 tests/migrate_pages--pidns-translation.c      |   2 +
 tests/migrate_pages.c                         |  13 +-
 tests/move_pages--pidns-translation.c         |   2 +
 tests/move_pages.c                            |  53 ++++--
 tests/net-sockaddr--pidns-translation.c       |   2 +
 tests/net-sockaddr.c                          |  68 +++++++-
 tests/netlink_audit--pidns-translation.c      |   2 +
 tests/netlink_audit--pidns-translation.test   |  13 ++
 tests/netlink_audit.c                         |  13 +-
 tests/pidfd_open--pidns-translation.c         |   2 +
 tests/pidfd_open.c                            |  23 ++-
 tests/pidfd_send_signal--pidns-translation.c  |   2 +
 tests/pidfd_send_signal.c                     |  15 +-
 tests/pidns.c                                 | 162 ++++++++++++++++++
 tests/pidns.h                                 |  41 +++++
 tests/prlimit64--pidns-translation.c          |   2 +
 tests/prlimit64.c                             |  19 +-
 tests/process_vm_readv--pidns-translation.c   |   2 +
 tests/process_vm_readv_writev.c               |  29 ++--
 tests/process_vm_writev--pidns-translation.c  |   2 +
 tests/rt_sigqueueinfo--pidns-translation.c    |   2 +
 tests/rt_sigqueueinfo.c                       |  17 +-
 tests/rt_tgsigqueueinfo--pidns-translation.c  |   2 +
 tests/rt_tgsigqueueinfo.c                     |  28 ++-
 tests/sched_xetaffinity--pidns-translation.c  |   2 +
 tests/sched_xetaffinity.c                     |  33 ++--
 tests/sched_xetattr--pidns-translation.c      |   2 +
 tests/sched_xetattr.c                         |  49 +++++-
 tests/sched_xetparam--pidns-translation.c     |   2 +
 tests/sched_xetparam.c                        |  22 ++-
 tests/sched_xetscheduler--pidns-translation.c |   2 +
 tests/sched_xetscheduler.c                    |  46 +++--
 tests/signal_receive--pidns-translation.c     |   2 +
 tests/signal_receive.c                        |  24 ++-
 tests/so_peercred--pidns-translation.c        |   2 +
 tests/so_peercred.c                           |  24 +++
 tests/xet_robust_list--pidns-translation.c    |   2 +
 tests/xet_robust_list.c                       |  20 ++-
 tests/xetpgid--pidns-translation.c            |   2 +
 tests/xetpgid.c                               |  23 ++-
 tests/xetpriority--pidns-translation.c        |   2 +
 tests/xetpriority.c                           |  22 ++-
 71 files changed, 1122 insertions(+), 167 deletions(-)
 create mode 100644 tests/fcntl--pidns-translation.c
 create mode 100644 tests/fcntl64--pidns-translation.c
 create mode 100644 tests/fork--pidns-translation.awk
 create mode 100644 tests/fork--pidns-translation.c
 create mode 100755 tests/fork--pidns-translation.test
 create mode 100644 tests/getpgrp--pidns-translation.c
 create mode 100644 tests/getpid--pidns-translation.c
 create mode 100644 tests/getsid--pidns-translation.c
 create mode 100644 tests/gettid--pidns-translation.c
 create mode 100644 tests/ioctl_block--pidns-translation.c
 create mode 100755 tests/ioctl_block--pidns-translation.test
 create mode 100644 tests/ioprio--pidns-translation.c
 create mode 100644 tests/kcmp-yY.c
 create mode 100644 tests/kill--pidns-translation.c
 create mode 100644 tests/migrate_pages--pidns-translation.c
 create mode 100644 tests/move_pages--pidns-translation.c
 create mode 100644 tests/net-sockaddr--pidns-translation.c
 create mode 100644 tests/netlink_audit--pidns-translation.c
 create mode 100755 tests/netlink_audit--pidns-translation.test
 create mode 100644 tests/pidfd_open--pidns-translation.c
 create mode 100644 tests/pidfd_send_signal--pidns-translation.c
 create mode 100644 tests/pidns.c
 create mode 100644 tests/pidns.h
 create mode 100644 tests/prlimit64--pidns-translation.c
 create mode 100644 tests/process_vm_readv--pidns-translation.c
 create mode 100644 tests/process_vm_writev--pidns-translation.c
 create mode 100644 tests/rt_sigqueueinfo--pidns-translation.c
 create mode 100644 tests/rt_tgsigqueueinfo--pidns-translation.c
 create mode 100644 tests/sched_xetaffinity--pidns-translation.c
 create mode 100644 tests/sched_xetattr--pidns-translation.c
 create mode 100644 tests/sched_xetparam--pidns-translation.c
 create mode 100644 tests/sched_xetscheduler--pidns-translation.c
 create mode 100644 tests/signal_receive--pidns-translation.c
 create mode 100644 tests/so_peercred--pidns-translation.c
 create mode 100644 tests/xet_robust_list--pidns-translation.c
 create mode 100644 tests/xetpgid--pidns-translation.c
 create mode 100644 tests/xetpriority--pidns-translation.c

diff --git a/tests/.gitignore b/tests/.gitignore
index 0896b258..2defa812 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -116,7 +116,9 @@ fchown
 fchown32
 fchownat
 fcntl
+fcntl--pidns-translation
 fcntl64
+fcntl64--pidns-translation
 fdatasync
 fflush
 file_handle
@@ -126,6 +128,7 @@ filter-unavailable
 finit_module
 flock
 fork-f
+fork--pidns-translation
 fsconfig
 fsconfig-P
 fsmount
@@ -168,7 +171,9 @@ getgroups
 getgroups32
 getpeername
 getpgrp
+getpgrp--pidns-translation
 getpid
+getpid--pidns-translation
 getppid
 getrandom
 getresgid
@@ -178,8 +183,10 @@ getresuid32
 getrlimit
 getrusage
 getsid
+getsid--pidns-translation
 getsockname
 gettid
+gettid--pidns-translation
 getuid
 getuid32
 getxgid
@@ -200,6 +207,7 @@ io_uring_register
 io_uring_setup
 ioctl
 ioctl_block
+ioctl_block--pidns-translation
 ioctl_dm
 ioctl_dm-v
 ioctl_evdev
@@ -275,6 +283,7 @@ ioctl_watchdog
 ioperm
 iopl
 ioprio
+ioprio--pidns-translation
 ioprio-Xabbrev
 ioprio-Xraw
 ioprio-Xverbose
@@ -299,6 +308,7 @@ ipc_shm-Xverbose
 is_linux_mips_n64
 kcmp
 kcmp-y
+kcmp-yY
 kern_features
 kernel_version
 kernel_version-Xabbrev
@@ -311,6 +321,7 @@ keyctl-Xabbrev
 keyctl-Xraw
 keyctl-Xverbose
 kill
+kill--pidns-translation
 kill_child
 ksysent
 ksysent.h
@@ -340,6 +351,7 @@ memfd_create-Xabbrev
 memfd_create-Xraw
 memfd_create-Xverbose
 migrate_pages
+migrate_pages--pidns-translation
 mincore
 mkdir
 mkdirat
@@ -371,6 +383,7 @@ move_pages
 move_pages-Xabbrev
 move_pages-Xraw
 move_pages-Xverbose
+move_pages--pidns-translation
 mq
 mq_sendrecv
 mq_sendrecv-read
@@ -391,6 +404,7 @@ net-packet_mreq-Xabbrev
 net-packet_mreq-Xraw
 net-packet_mreq-Xverbose
 net-sockaddr
+net-sockaddr--pidns-translation
 net-tpacket_req
 net-tpacket_stats
 net-tpacket_stats-success
@@ -400,6 +414,7 @@ net-yy-inet6
 net-yy-netlink
 net-yy-unix
 netlink_audit
+netlink_audit--pidns-translation
 netlink_crypto
 netlink_generic
 netlink_inet_diag
@@ -507,7 +522,9 @@ pidfd_open--decode-fd-socket
 pidfd_open-P
 pidfd_open-y
 pidfd_open-yy
+pidfd_open--pidns-translation
 pidfd_send_signal
+pidfd_send_signal--pidns-translation
 pipe
 pipe2
 pkey_alloc
@@ -546,8 +563,11 @@ printstrn-umoven
 printstrn-umoven-peekdata
 printstrn-umoven-undumpable
 prlimit64
+prlimit64--pidns-translation
 process_vm_readv
+process_vm_readv--pidns-translation
 process_vm_writev
+process_vm_writev--pidns-translation
 pselect6
 ptrace
 ptrace_syscall_info
@@ -597,10 +617,12 @@ rt_sigaction
 rt_sigpending
 rt_sigprocmask
 rt_sigqueueinfo
+rt_sigqueueinfo--pidns-translation
 rt_sigreturn
 rt_sigsuspend
 rt_sigtimedwait
 rt_tgsigqueueinfo
+rt_tgsigqueueinfo--pidns-translation
 run_expect_termsig
 s390_guarded_storage
 s390_guarded_storage-v
@@ -611,9 +633,13 @@ s390_sthyi-v
 sched_get_priority_mxx
 sched_rr_get_interval
 sched_xetaffinity
+sched_xetaffinity--pidns-translation
 sched_xetattr
+sched_xetattr--pidns-translation
 sched_xetparam
+sched_xetparam--pidns-translation
 sched_xetscheduler
+sched_xetscheduler--pidns-translation
 sched_yield
 scm_rights
 scno.h
@@ -669,6 +695,7 @@ sigaltstack
 siginfo
 signal
 signal_receive
+signal_receive--pidns-translation
 signalfd4
 sigpending
 sigprocmask
@@ -681,6 +708,7 @@ so_peercred
 so_peercred-Xabbrev
 so_peercred-Xraw
 so_peercred-Xverbose
+so_peercred--pidns-translation
 sock_filter-v
 sock_filter-v-Xabbrev
 sock_filter-v-Xraw
@@ -781,9 +809,12 @@ waitpid
 xattr
 xattr-strings
 xet_robust_list
+xet_robust_list--pidns-translation
 xet_thread_area_x86
 xetitimer
 xetpgid
+xetpgid--pidns-translation
 xetpriority
+xetpriority--pidns-translation
 xettimeofday
 zeroargc
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 28d95e39..451a8c2a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -44,6 +44,8 @@ libtests_a_SOURCES = \
 	libsocketcall.c \
 	lock_file.c \
 	overflowuid.c \
+	pidns.c \
+	pidns.h \
 	pipe_maxfd.c \
 	print_quoted_string.c \
 	print_time.c \
@@ -107,17 +109,25 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
 	delay \
 	execve-v \
 	execveat-v \
+	fcntl--pidns-translation \
+	fcntl64--pidns-translation \
 	filter_seccomp-flag \
 	filter_seccomp-perf \
 	filter-unavailable \
 	fork-f \
+	fork--pidns-translation \
 	fsync-y \
 	get_process_reaper \
+	getpgrp--pidns-translation	\
 	getpid	\
+	getpid--pidns-translation	\
 	getppid	\
+	getsid--pidns-translation \
 	gettid \
+	gettid--pidns-translation \
 	inject-nf \
 	int_0x80 \
+	ioctl_block--pidns-translation \
 	ioctl_dm-v \
 	ioctl_evdev-success \
 	ioctl_evdev-success-Xabbrev \
@@ -148,18 +158,25 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
 	ioctl_v4l2-success-v-Xabbrev \
 	ioctl_v4l2-success-v-Xraw \
 	ioctl_v4l2-success-v-Xverbose \
+	ioprio--pidns-translation \
 	is_linux_mips_n64 \
+	kcmp-yY \
 	kill_child \
+	kill--pidns-translation \
 	ksysent \
 	list_sigaction_signum \
 	localtime \
 	looping_threads \
+	migrate_pages--pidns-translation \
 	mmsg-silent \
 	mmsg_name-v \
+	move_pages--pidns-translation \
 	msg_control-v \
 	net-accept-connect \
+	net-sockaddr--pidns-translation \
 	net-tpacket_stats-success \
 	nlattr_ifla_xdp-y \
+	netlink_audit--pidns-translation \
 	netlink_inet_diag \
 	netlink_netlink_diag \
 	netlink_unix_diag \
@@ -171,14 +188,19 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
 	pc \
 	perf_event_open_nonverbose \
 	perf_event_open_unabbrev \
+	pidfd_open--pidns-translation \
+	pidfd_send_signal--pidns-translation \
 	poll-P \
 	ppoll-P \
 	ppoll-v \
+	prlimit64--pidns-translation \
 	prctl-seccomp-filter-v \
 	prctl-seccomp-strict \
 	prctl-spec-inject \
 	print_maxfd \
 	print_ppid_tracerpid \
+	process_vm_readv--pidns-translation \
+	process_vm_writev--pidns-translation \
 	qual_fault \
 	qual_inject-error-signal \
 	qual_inject-retval \
@@ -192,7 +214,13 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
 	quotactl-xfs-v \
 	redirect-fds \
 	restart_syscall \
+	rt_sigqueueinfo--pidns-translation \
+	rt_tgsigqueueinfo--pidns-translation \
 	run_expect_termsig \
+	sched_xetaffinity--pidns-translation \
+	sched_xetattr--pidns-translation \
+	sched_xetparam--pidns-translation \
+	sched_xetscheduler--pidns-translation \
 	scm_rights \
 	seccomp-filter-v \
 	seccomp-strict \
@@ -202,12 +230,14 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
 	set_sigign \
 	setpgrp-exec \
 	signal_receive \
+	signal_receive--pidns-translation \
 	sleep \
 	stack-fcall \
 	stack-fcall-attach \
 	stack-fcall-mangled \
 	status-none-threads \
 	status-unfinished-threads \
+	so_peercred--pidns-translation \
 	syslog-success \
 	threads-execve \
 	threads-execve--quiet-thread-execve \
@@ -221,6 +251,9 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
 	vfork-f \
 	wait4-v \
 	waitid-v \
+	xetpgid--pidns-translation \
+	xetpriority--pidns-translation \
+	xet_robust_list--pidns-translation \
 	zeroargc \
 	# end of check_PROGRAMS
 
@@ -308,6 +341,7 @@ DECODER_TESTS = \
 	int_0x80.test \
 	inotify_init-y.test \
 	ioctl.test \
+	ioctl_block--pidns-translation.test \
 	ioctl_evdev-success.test \
 	ipc_msgbuf.test \
 	kern_features-fault.test \
@@ -379,12 +413,14 @@ MISC_TESTS = \
 	filtering_fd-syntax.test \
 	filtering_syscall-syntax.test \
 	first_exec_failure.test \
+	fork--pidns-translation.test \
 	get_regs.test \
 	inject-nf.test \
 	interactive_block.test \
 	kill_child.test \
 	localtime.test \
 	looping_threads.test \
+	netlink_audit--pidns-translation.test \
 	opipe.test \
 	options-syntax.test \
 	pc.test \
@@ -465,6 +501,7 @@ EXTRA_DIST = \
 	filter_seccomp.in \
 	filter_seccomp.sh \
 	filter-unavailable.expected \
+	fork--pidns-translation.awk \
 	fstatat.c \
 	fstatx.c \
 	gen_pure_executables.sh \
diff --git a/tests/fcntl--pidns-translation.c b/tests/fcntl--pidns-translation.c
new file mode 100644
index 00000000..e249424a
--- /dev/null
+++ b/tests/fcntl--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "fcntl.c"
diff --git a/tests/fcntl-common.c b/tests/fcntl-common.c
index 27694326..7ffb4acc 100644
--- a/tests/fcntl-common.c
+++ b/tests/fcntl-common.c
@@ -13,6 +13,8 @@
 #include <unistd.h>
 #include <assert.h>
 #include "flock.h"
+#include "pidns.h"
+#include "scno.h"
 
 #define FILE_LEN 4096
 
@@ -48,12 +50,14 @@ test_flock_einval(const int cmd, const char *name)
 	fl->l_len = (TYPEOF_FLOCK_OFF_T) 0xdefaced2cafef00dULL;
 
 	invoke_test_syscall(0, cmd, fl);
+	pidns_print_leader();
 	printf("%s(0, %s, {l_type=F_RDLCK, l_whence=SEEK_SET"
 	       ", l_start=%jd, l_len=%jd}) = %s\n", TEST_SYSCALL_STR, name,
 	       (intmax_t) fl->l_start, (intmax_t) fl->l_len, errstr);
 
 	void *const bad_addr = (void *) fl + 1;
 	invoke_test_syscall(0, cmd, bad_addr);
+	pidns_print_leader();
 	printf("%s(0, %s, %p) = %s\n",
 	       TEST_SYSCALL_STR, name, bad_addr, errstr);
 }
@@ -72,12 +76,14 @@ test_flock64_einval(const int cmd, const char *name)
 	fl->l_len = (TYPEOF_FLOCK_OFF_T) 0xdefaced2cafef00dULL;
 
 	invoke_test_syscall(0, cmd, fl);
+	pidns_print_leader();
 	printf("%s(0, %s, {l_type=F_RDLCK, l_whence=SEEK_SET"
 	       ", l_start=%jd, l_len=%jd}) = %s\n", TEST_SYSCALL_STR, name,
 	       (intmax_t) fl->l_start, (intmax_t) fl->l_len, errstr);
 
 	void *const bad_addr = (void *) fl + 1;
 	invoke_test_syscall(0, cmd, bad_addr);
+	pidns_print_leader();
 	printf("%s(0, %s, %p) = %s\n",
 	       TEST_SYSCALL_STR, name, bad_addr, errstr);
 }
@@ -94,6 +100,7 @@ test_flock(void)
 	fl->l_len = FILE_LEN;
 
 	long rc = invoke_test_syscall(0, F_SETLK, fl);
+	pidns_print_leader();
 	printf("%s(0, F_SETLK, {l_type=F_RDLCK, l_whence=SEEK_SET"
 	       ", l_start=0, l_len=%d}) = %s\n",
 	       TEST_SYSCALL_STR, FILE_LEN, errstr);
@@ -101,11 +108,13 @@ test_flock(void)
 		return;
 
 	invoke_test_syscall(0, F_GETLK, fl);
+	pidns_print_leader();
 	printf("%s(0, F_GETLK, {l_type=F_UNLCK, l_whence=SEEK_SET"
 	       ", l_start=0, l_len=%d, l_pid=0}) = 0\n",
 	       TEST_SYSCALL_STR, FILE_LEN);
 
 	invoke_test_syscall(0, F_SETLKW, fl);
+	pidns_print_leader();
 	printf("%s(0, F_SETLKW, {l_type=F_UNLCK, l_whence=SEEK_SET"
 	       ", l_start=0, l_len=%d}) = 0\n",
 	       TEST_SYSCALL_STR, FILE_LEN);
@@ -124,6 +133,7 @@ test_flock64_ofd(void)
 	fl->l_len = FILE_LEN;
 
 	long rc = invoke_test_syscall(0, F_OFD_SETLK, fl);
+	pidns_print_leader();
 	printf("%s(0, F_OFD_SETLK, {l_type=F_RDLCK, l_whence=SEEK_SET"
 	       ", l_start=0, l_len=%d}) = %s\n",
 	       TEST_SYSCALL_STR, FILE_LEN, errstr);
@@ -131,11 +141,13 @@ test_flock64_ofd(void)
 		return;
 
 	invoke_test_syscall(0, F_OFD_GETLK, fl);
+	pidns_print_leader();
 	printf("%s(0, F_OFD_GETLK, {l_type=F_UNLCK, l_whence=SEEK_SET"
 	       ", l_start=0, l_len=%d, l_pid=0}) = 0\n",
 	       TEST_SYSCALL_STR, FILE_LEN);
 
 	invoke_test_syscall(0, F_OFD_SETLKW, fl);
+	pidns_print_leader();
 	printf("%s(0, F_OFD_SETLKW, {l_type=F_UNLCK, l_whence=SEEK_SET"
 	       ", l_start=0, l_len=%d}) = 0\n",
 	       TEST_SYSCALL_STR, FILE_LEN);
@@ -167,18 +179,21 @@ test_flock64(void)
 static long
 test_f_owner_ex_type_pid(const int cmd, const char *const cmd_name,
 			 const int type, const char *const type_name,
-			 pid_t pid)
+			 enum pid_type pid_type, pid_t pid)
 {
 	TAIL_ALLOC_OBJECT_CONST_PTR(struct_kernel_f_owner_ex, fo);
 
 	fo->type = type;
 	fo->pid = pid;
 	long rc = invoke_test_syscall(0, cmd, fo);
-	printf("%s(0, %s, {type=%s, pid=%d}) = %s\n",
-	       TEST_SYSCALL_STR, cmd_name, type_name, fo->pid, errstr);
+	pidns_print_leader();
+	printf("%s(0, %s, {type=%s, pid=%d%s}) = %s\n",
+	       TEST_SYSCALL_STR, cmd_name, type_name,
+	       fo->pid, pidns_pid2str(pid_type), errstr);
 
 	void *bad_addr = (void *) fo + 1;
 	invoke_test_syscall(0, cmd, bad_addr);
+	pidns_print_leader();
 	printf("%s(0, %s, %p) = %s\n",
 	       TEST_SYSCALL_STR, cmd_name, bad_addr, errstr);
 
@@ -187,35 +202,43 @@ test_f_owner_ex_type_pid(const int cmd, const char *const cmd_name,
 
 static void
 test_f_owner_ex_umove_or_printaddr(const int type, const char *const type_name,
-				   pid_t pid)
+				   enum pid_type pid_type, pid_t pid)
 {
 	long rc = test_f_owner_ex_type_pid(ARG_STR(F_SETOWN_EX),
-					   type, type_name, pid);
+					   type, type_name, pid_type, pid);
 	if (!rc)
 		test_f_owner_ex_type_pid(ARG_STR(F_GETOWN_EX),
-					 type, type_name, pid);
+					 type, type_name, pid_type, pid);
 }
 
 static void
 test_f_owner_ex(void)
 {
-	static const struct {
+	struct {
 		int type;
 		const char *type_name;
-		pid_t pid[2];
+		enum pid_type pid_type;
+		pid_t pid;
 	} a[] = {
-		{ ARG_STR(F_OWNER_TID), { 1234567890, 20 } },
-		{ ARG_STR(F_OWNER_PID), { 1298126790, 30 } },
-		{ ARG_STR(F_OWNER_PGRP), { 1294567890, 40 } }
+		{ ARG_STR(F_OWNER_TID), PT_NONE, 1234567890 },
+		{ ARG_STR(F_OWNER_PID), PT_NONE, 1234567890 },
+		{ ARG_STR(F_OWNER_PGRP), PT_NONE, 1234567890 },
+		{ ARG_STR(F_OWNER_TID), PT_TID, 0 },
+		{ ARG_STR(F_OWNER_PID), PT_TGID, 0 },
+		{ ARG_STR(F_OWNER_PGRP), PT_PGID, 0 },
 	};
 
-	for (unsigned int i = 0; i < ARRAY_SIZE(a); i++) {
-		for (unsigned int j = 0; j < ARRAY_SIZE(a[0].pid); j++) {
-			test_f_owner_ex_umove_or_printaddr(a[i].type,
-							   a[i].type_name,
-							   a[i].pid[j]);
-		}
-	}
+#ifdef __NR_gettid
+	a[3].pid = syscall(__NR_gettid);
+#else
+	a[3].pid_type = PT_NONE;
+#endif
+	a[4].pid = getpid();
+	a[5].pid = getpgid(0);
+
+	for (unsigned int i = 0; i < ARRAY_SIZE(a); i++)
+		test_f_owner_ex_umove_or_printaddr(a[i].type, a[i].type_name,
+			a[i].pid_type, a[i].pid);
 }
 #endif /* TEST_F_OWNER_EX */
 
@@ -228,6 +251,23 @@ struct fcntl_cmd_check {
 	void (*print_flags)(long rc);
 };
 
+static void
+test_xetown(void)
+{
+	const int pid = getpid();
+	const char *pid_str = pidns_pid2str(PT_TGID);
+
+	invoke_test_syscall(0, F_SETOWN, (void *) (intptr_t) pid);
+	pidns_print_leader();
+	printf("%s(0, F_SETOWN, %d%s) = %s\n",
+		TEST_SYSCALL_STR, pid, pid_str, errstr);
+
+	invoke_test_syscall(0, F_GETOWN, NULL);
+	pidns_print_leader();
+	printf("%s(0, F_GETOWN) = %d%s\n",
+		TEST_SYSCALL_STR, pid, pid_str);
+}
+
 static void
 print_retval_flags(const struct fcntl_cmd_check *check, long rc)
 {
@@ -243,12 +283,14 @@ static void
 test_other_set_cmd(const struct fcntl_cmd_check *check)
 {
 	invoke_test_syscall(check->fd, check->cmd, (void *) check->arg);
+	pidns_print_leader();
 	printf("%s(%d, %s, %s) = %s\n",
 	       TEST_SYSCALL_STR, check->fd,
 	       check->cmd_str, check->arg_str, errstr);
 
 	/* bad file fd */
 	invoke_test_syscall(-1, check->cmd, (void *) check->arg);
+	pidns_print_leader();
 	printf("%s(-1, %s, %s) = %s\n",
 	       TEST_SYSCALL_STR, check->cmd_str,
 	       check->arg_str, errstr);
@@ -258,12 +300,14 @@ static void
 test_other_get_cmd(const struct fcntl_cmd_check *check)
 {
 	long rc = invoke_test_syscall(check->fd, check->cmd, NULL);
+	pidns_print_leader();
 	printf("%s(%d, %s) = ",
 	       TEST_SYSCALL_STR, check->fd, check->cmd_str);
 	print_retval_flags(check, rc);
 
 	/* bad file fd */
 	invoke_test_syscall(-1, check->cmd, NULL);
+	pidns_print_leader();
 	printf("%s(-1, %s) = %s\n",
 	       TEST_SYSCALL_STR, check->cmd_str, errstr);
 }
@@ -315,7 +359,6 @@ test_fcntl_others(void)
 {
 	static const struct fcntl_cmd_check set_checks[] = {
 		{ 0, ARG_STR(F_SETFD), ARG_STR(FD_CLOEXEC) },
-		{ 0, ARG_STR(F_SETOWN), ARG_STR(20) },
 #ifdef F_SETPIPE_SZ
 		{ 0, ARG_STR(F_SETPIPE_SZ), ARG_STR(4097) },
 #endif
@@ -336,7 +379,6 @@ test_fcntl_others(void)
 	static const struct fcntl_cmd_check get_checks[] = {
 		{ 0, ARG_STR(F_GETFD), .print_flags = print_flags_getfd },
 		{ 1, ARG_STR(F_GETFD), .print_flags = print_flags_getfd },
-		{ 0, ARG_STR(F_GETOWN) },
 #ifdef F_GETPIPE_SZ
 		{ 0, ARG_STR(F_GETPIPE_SZ) },
 #endif
@@ -360,6 +402,10 @@ create_sample(void)
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	create_sample();
 	test_flock();
 	test_flock64();
@@ -367,7 +413,9 @@ main(void)
 	test_f_owner_ex();
 #endif
 	test_fcntl_others();
+	test_xetown();
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/fcntl.c b/tests/fcntl.c
index f38b8afb..673c06e4 100644
--- a/tests/fcntl.c
+++ b/tests/fcntl.c
@@ -24,6 +24,7 @@ test_flock64_undecoded(const int cmd, const char *name)
 		.l_len = 0xdefaced2cafef00dULL
 	};
 	invoke_test_syscall(0, cmd, &fl);
+	pidns_print_leader();
 	printf("%s(0, %s, %p) = %s\n",
 	       TEST_SYSCALL_STR, name, &fl, errstr);
 }
diff --git a/tests/fcntl64--pidns-translation.c b/tests/fcntl64--pidns-translation.c
new file mode 100644
index 00000000..c6fdadd1
--- /dev/null
+++ b/tests/fcntl64--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "fcntl64.c"
diff --git a/tests/fcntl64.c b/tests/fcntl64.c
index 78e53b0d..f7b3f2fb 100644
--- a/tests/fcntl64.c
+++ b/tests/fcntl64.c
@@ -27,6 +27,7 @@ test_flock64_lk64(void)
 	fl->l_len = FILE_LEN;
 
 	long rc = invoke_test_syscall(0, F_SETLK64, fl);
+	pidns_print_leader();
 	printf("%s(0, F_SETLK64, {l_type=F_RDLCK, l_whence=SEEK_SET"
 	       ", l_start=0, l_len=%d}) = %s\n",
 	       TEST_SYSCALL_STR, FILE_LEN, errstr);
@@ -35,11 +36,13 @@ test_flock64_lk64(void)
 		return;
 
 	invoke_test_syscall(0, F_GETLK64, fl);
+	pidns_print_leader();
 	printf("%s(0, F_GETLK64, {l_type=F_UNLCK, l_whence=SEEK_SET"
 	       ", l_start=0, l_len=%d, l_pid=0}) = 0\n",
 	       TEST_SYSCALL_STR, FILE_LEN);
 
 	invoke_test_syscall(0, F_SETLKW64, fl);
+	pidns_print_leader();
 	printf("%s(0, F_SETLKW64, {l_type=F_UNLCK, l_whence=SEEK_SET"
 	       ", l_start=0, l_len=%d}) = 0\n",
 	       TEST_SYSCALL_STR, FILE_LEN);
diff --git a/tests/fork--pidns-translation.awk b/tests/fork--pidns-translation.awk
new file mode 100644
index 00000000..dd007a33
--- /dev/null
+++ b/tests/fork--pidns-translation.awk
@@ -0,0 +1,8 @@
+NR == 2 {
+        strace_pid=$6
+}
+
+NR == 3 {
+        if (strace_pid != $1)
+                exit 1
+}
diff --git a/tests/fork--pidns-translation.c b/tests/fork--pidns-translation.c
new file mode 100644
index 00000000..9c341e6a
--- /dev/null
+++ b/tests/fork--pidns-translation.c
@@ -0,0 +1,62 @@
+/*
+ * Test PID namespace translation
+ *
+ * Copyright (c) 2020 Ákos Uzonyi <uzonyi.akos at gmail.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "tests.h"
+#include "scno.h"
+
+#ifdef __NR_fork
+
+#include <errno.h>
+#include <limits.h>
+#include <sched.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <linux/sched.h>
+
+static int
+fork_chain(int depth)
+{
+	if (!depth)
+		return 0;
+
+	int pid = syscall(__NR_fork);
+	if (pid < 0)
+		return errno;
+
+	if (!pid)
+		_exit(fork_chain(depth - 1));
+
+	int status;
+	if (wait(&status) < 0)
+		return errno;
+
+	if (!WIFEXITED(status))
+		return -1;
+
+	return WEXITSTATUS(status);
+}
+
+int main(void)
+{
+	if (unshare(CLONE_NEWPID | CLONE_NEWUSER) < 0)
+		perror_msg_and_fail("unshare");
+
+	errno = fork_chain(2);
+	if (errno)
+		perror("fork_chain");
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_fork")
+
+#endif
diff --git a/tests/fork--pidns-translation.test b/tests/fork--pidns-translation.test
new file mode 100755
index 00000000..f4a83045
--- /dev/null
+++ b/tests/fork--pidns-translation.test
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Check pidns translation of fork's return value.
+#
+# Copyright (c) 2020 The strace developers.
+# All rights reserved.
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+. "${srcdir=.}/init.sh"
+
+run_prog
+run_strace -a6 --pidns-translation -f -e signal=none -e trace=fork $args
+match_awk
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 540ba61b..b2c06cef 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -93,7 +93,9 @@ fchown	-a16
 fchown32	-a18
 fchownat
 fcntl	-a8
+fcntl--pidns-translation	test_pidns -a8 -e trace=fcntl
 fcntl64	-a8
+fcntl64--pidns-translation	test_pidns -a8 -e trace=fcntl64
 fdatasync	-a14
 file_handle	-e trace=name_to_handle_at,open_by_handle_at
 file_ioctl	+ioctl.test
@@ -147,7 +149,9 @@ getgroups	-a17
 getgroups32	-a19
 getpeername	-a27
 getpgrp	-a10
+getpgrp--pidns-translation	test_pidns -e trace=getpgrp -a10
 getpid	-a9
+getpid--pidns-translation	test_pidns -e trace=getpid -a9
 getppid	-a10
 getrandom	-a32 -s3
 getresgid	-a25
@@ -157,8 +161,10 @@ getresuid32	-a27
 getrlimit	-a27
 getrusage	-v
 getsid	-a10
+getsid--pidns-translation	test_pidns -e trace=getsid -a10
 getsockname	-a27
 gettid	-a9
+gettid--pidns-translation	test_pidns -e trace=gettid -a9
 getuid-creds	+getuid.test
 getuid32	+getuid.test
 getuid32-creds	+getuid.test
@@ -250,6 +256,7 @@ ioctl_watchdog	+ioctl.test
 ioperm	-a27
 iopl	-a8
 ioprio	-a18 -e trace=ioprio_get,ioprio_set
+ioprio--pidns-translation	test_pidns -a18 -e trace=ioprio_get,ioprio_set
 ioprio-Xabbrev	-a18 -e trace=ioprio_get,ioprio_set -Xabbrev
 ioprio-Xraw	-a18 -e trace=ioprio_get,ioprio_set -Xraw
 ioprio-Xverbose	-a18 -e trace=ioprio_get,ioprio_set -Xverbose
@@ -272,6 +279,7 @@ ipc_shm-Xraw	+ipc.sh -Xraw -a19
 ipc_shm-Xverbose	+ipc.sh -Xverbose -a34
 kcmp	-a22
 kcmp-y	-a22 -y -e trace=kcmp
+kcmp-yY	test_pidns -a22 -y -e trace=kcmp
 kern_features -a16
 kernel_version	-a16 -v -e trace=bpf
 kernel_version-Xabbrev	-a16 -Xabbrev -v -e trace=bpf
@@ -284,6 +292,7 @@ keyctl-Xabbrev	-a31 -s10 -e trace=keyctl -Xabbrev
 keyctl-Xraw	-a13 -s10 -e trace=keyctl -Xraw
 keyctl-Xverbose	-a41 -s10 -e trace=keyctl -Xverbose
 kill	-a12 -esignal=none
+kill--pidns-translation	test_pidns -a12 -e trace=kill -esignal=none
 ksysent	../$NAME
 lchown	-a30
 lchown32	-a32
@@ -305,6 +314,7 @@ memfd_create-Xabbrev	-Xabbrev -e trace=memfd_create
 memfd_create-Xraw	-a30 -Xraw -e trace=memfd_create
 memfd_create-Xverbose	-Xverbose -e trace=memfd_create
 migrate_pages	-a33
+migrate_pages--pidns-translation	test_pidns -a33 -e trace=migrate_pages
 mincore	-a22
 mkdir	-a20
 mkdirat	-a28
@@ -335,6 +345,7 @@ move_pages	-s3
 move_pages-Xabbrev	-s3 -e trace=move_pages -Xabbrev
 move_pages-Xraw	-s3 -a36 -e trace=move_pages -Xraw
 move_pages-Xverbose	-s3 -e trace=move_pages -Xverbose
+move_pages--pidns-translation	test_pidns -s3 -e trace=move_pages
 mq	-a32 -e trace=mq_getsetattr,mq_open,mq_unlink
 mq_sendrecv	-a14 -e trace=mq_open,mq_notify,mq_timedsend,mq_timedreceive,mq_unlink
 mq_sendrecv-read	-eread=0 -a14 -e trace=mq_open,mq_notify,mq_timedsend,mq_timedreceive,mq_unlink
@@ -354,6 +365,7 @@ net-packet_mreq-Xabbrev	-e trace=setsockopt -Xabbrev
 net-packet_mreq-Xraw	-e trace=setsockopt -Xraw
 net-packet_mreq-Xverbose	-e trace=setsockopt -Xverbose
 net-sockaddr	-a24 -e trace=connect
+net-sockaddr--pidns-translation	test_pidns -a24 -e trace=connect
 net-tpacket_req -e trace=setsockopt
 net-tpacket_stats -e trace=getsockopt
 net-yy-inet6	+net-yy-inet.test
@@ -457,7 +469,9 @@ pidfd_open--decode-fd-socket	-a17 -e decode-fd=socket -e trace=pidfd_open
 pidfd_open-P	-a17 -P /dev/full -e trace=pidfd_open
 pidfd_open-y	-a17 -y -e trace=pidfd_open
 pidfd_open-yy	-a17 -yy -e trace=pidfd_open
+pidfd_open--pidns-translation	test_pidns -a17 -e trace=pidfd_open
 pidfd_send_signal
+pidfd_send_signal--pidns-translation test_pidns -e trace=pidfd_send_signal
 pipe2	-a15
 pkey_alloc	-a17
 pkey_free	-a13
@@ -480,8 +494,11 @@ printstrn-umoven	-s4096 -e signal=none -e trace=add_key
 printstrn-umoven-peekdata	-e signal=none -e trace=add_key
 printstrn-umoven-undumpable	-e signal=none -e trace=add_key
 prlimit64
+prlimit64--pidns-translation     test_pidns -e trace=prlimit64
 process_vm_readv	-s5 -a37
+process_vm_readv--pidns-translation	test_pidns -s5 -a37 -e trace=process_vm_readv
 process_vm_writev	-s5 -a38
+process_vm_writev--pidns-translation	test_pidns -s5 -a38 -e trace=process_vm_writev
 pselect6
 ptrace	-a23 -e signal=none
 ptrace_syscall_info	-a35 -e signal=none -e trace=ptrace
@@ -518,10 +535,12 @@ rmdir	-a22
 rt_sigpending	-a20
 rt_sigprocmask
 rt_sigqueueinfo	-esignal=none
+rt_sigqueueinfo--pidns-translation	test_pidns -esignal=none -e trace=rt_sigqueueinfo
 rt_sigreturn	-esignal='!USR1'
 rt_sigsuspend	-a20 -esignal=none
 rt_sigtimedwait	-a38
 rt_tgsigqueueinfo	-esignal=none
+rt_tgsigqueueinfo--pidns-translation	test_pidns -esignal=none -e trace=rt_tgsigqueueinfo
 s390_guarded_storage	-a32
 s390_guarded_storage-v	-e trace=s390_guarded_storage -a32 -v
 s390_pci_mmio_read_write	-e trace=s390_pci_mmio_read,s390_pci_mmio_write -a30
@@ -532,9 +551,13 @@ sched	test_trace_expr times -e/sched
 sched_get_priority_mxx	-a33 -e trace=sched_get_priority_min,sched_get_priority_max
 sched_rr_get_interval	-a31
 sched_xetaffinity	-a28 -e trace=sched_getaffinity,sched_setaffinity
+sched_xetaffinity--pidns-translation	test_pidns -a28 -e trace=sched_getaffinity,sched_setaffinity
 sched_xetattr	-a29 -e trace=sched_getattr,sched_setattr
+sched_xetattr--pidns-translation	test_pidns -a29 -e trace=sched_getattr,sched_setattr
 sched_xetparam	-a23 -e trace=sched_getparam,sched_setparam
+sched_xetparam--pidns-translation	test_pidns -a23 -e trace=sched_getparam,sched_setparam
 sched_xetscheduler	-a22 -e trace=sched_getscheduler,sched_setscheduler
+sched_xetscheduler--pidns-translation	test_pidns -a22 -e trace=sched_getscheduler,sched_setscheduler
 sched_yield	-a14
 seccomp-filter	-e trace=seccomp
 seccomp-filter-v	-v -e trace=seccomp
@@ -581,6 +604,7 @@ sigaction	-a31
 siginfo	-e trace=none
 signal	-a25 -e signal=none -e trace='/^signal$'
 signal_receive	-a16 -e trace=kill
+signal_receive--pidns-translation	test_pidns -a16 -e trace=kill
 signalfd4
 sigpending	-a15
 sigprocmask	-a34
@@ -592,6 +616,7 @@ so_peercred	-e trace=getsockopt
 so_peercred-Xabbrev	-e trace=getsockopt -Xabbrev
 so_peercred-Xraw	-e trace=getsockopt -Xraw -a39
 so_peercred-Xverbose	-e trace=getsockopt -Xverbose
+so_peercred--pidns-translation	test_pidns -e trace=getsockopt
 sock_filter-v	-v -e trace=getsockopt,setsockopt
 sock_filter-v-Xabbrev	-v -e trace=getsockopt,setsockopt -X abbrev
 sock_filter-v-Xraw	-a 37 -v -e trace=getsockopt,setsockopt -X raw
@@ -719,7 +744,10 @@ waitpid	-a28
 xattr	-a22 -e trace=getxattr,fgetxattr,lgetxattr,setxattr,fsetxattr,lsetxattr,listxattr,flistxattr,llistxattr,removexattr,fremovexattr,lremovexattr
 xattr-strings	-a22 -s 4 -e trace=fsetxattr
 xet_robust_list	-a24 -e trace=get_robust_list,set_robust_list
+xet_robust_list--pidns-translation	test_pidns -a24 -e trace=get_robust_list,set_robust_list
 xetitimer	-a29 -e trace=setitimer,getitimer
 xetpgid	-a11 -e trace=getpgid,setpgid
+xetpgid--pidns-translation	test_pidns -a11 -e trace=getpgid,setpgid
 xetpriority	-a29 -e trace=getpriority,setpriority
+xetpriority--pidns-translation	test_pidns -a29 -e trace=getpriority,setpriority
 xettimeofday	-a20 -e trace=gettimeofday,settimeofday
diff --git a/tests/getpgrp--pidns-translation.c b/tests/getpgrp--pidns-translation.c
new file mode 100644
index 00000000..de8ceb33
--- /dev/null
+++ b/tests/getpgrp--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "getpgrp.c"
diff --git a/tests/getpgrp.c b/tests/getpgrp.c
index 104f4811..785d763d 100644
--- a/tests/getpgrp.c
+++ b/tests/getpgrp.c
@@ -7,6 +7,7 @@
 
 #include "tests.h"
 #include "scno.h"
+#include "pidns.h"
 
 #ifdef __NR_getpgrp
 
@@ -16,8 +17,15 @@
 int
 main(void)
 {
-	printf("getpgrp() = %ld\n", syscall(__NR_getpgrp));
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
+	pidns_print_leader();
+	printf("getpgrp() = %d%s\n", (int) syscall(__NR_getpgrp),
+		pidns_pid2str(PT_PGID));
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/getpid--pidns-translation.c b/tests/getpid--pidns-translation.c
new file mode 100644
index 00000000..94b12a1a
--- /dev/null
+++ b/tests/getpid--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "getpid.c"
diff --git a/tests/getpid.c b/tests/getpid.c
index 988f19d5..6a60ad6b 100644
--- a/tests/getpid.c
+++ b/tests/getpid.c
@@ -7,6 +7,7 @@
 
 #include "tests.h"
 #include "scno.h"
+#include "pidns.h"
 
 #if defined __NR_getpid && (!defined __NR_getxpid || __NR_getxpid != __NR_getpid)
 
@@ -16,7 +17,14 @@
 int
 main(void)
 {
-	printf("getpid() = %ld\n", syscall(__NR_getpid));
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
+	pidns_print_leader();
+	printf("getpid() = %d%s\n", (int) syscall(__NR_getpid),
+		pidns_pid2str(PT_TGID));
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/getsid--pidns-translation.c b/tests/getsid--pidns-translation.c
new file mode 100644
index 00000000..7f983e87
--- /dev/null
+++ b/tests/getsid--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "getsid.c"
diff --git a/tests/getsid.c b/tests/getsid.c
index 588ea4ab..4832b03c 100644
--- a/tests/getsid.c
+++ b/tests/getsid.c
@@ -6,15 +6,24 @@
  */
 
 #include "tests.h"
+#include "pidns.h"
+
 #include <stdio.h>
 #include <unistd.h>
 
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	pid_t pid = getpid();
-	printf("getsid(%d) = %d\n", pid, getsid(pid));
+	pidns_print_leader();
+	printf("getsid(%d%s) = %d%s\n", pid, pidns_pid2str(PT_TGID),
+		getsid(pid), pidns_pid2str(PT_SID));
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/gettid--pidns-translation.c b/tests/gettid--pidns-translation.c
new file mode 100644
index 00000000..500c3213
--- /dev/null
+++ b/tests/gettid--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "gettid.c"
diff --git a/tests/gettid.c b/tests/gettid.c
index d38918dd..b910d379 100644
--- a/tests/gettid.c
+++ b/tests/gettid.c
@@ -9,11 +9,19 @@
 #include <stdio.h>
 #include <unistd.h>
 #include "scno.h"
+#include "pidns.h"
 
 int
 main(void)
 {
-	printf("gettid() = %ld\n", syscall(__NR_gettid));
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
+	pidns_print_leader();
+	printf("gettid() = %d%s\n", (int) syscall(__NR_gettid),
+		pidns_pid2str(PT_TID));
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/init.sh b/tests/init.sh
index d78e697b..45c30090 100644
--- a/tests/init.sh
+++ b/tests/init.sh
@@ -387,6 +387,36 @@ test_prog_set()
 	test_pure_prog_set "$@" < "$srcdir/$NAME.in"
 }
 
+test_pidns_run_strace()
+{
+	local parent_pid
+
+	check_prog tail
+	check_prog cut
+	check_prog grep
+
+	run_prog > /dev/null
+	run_strace --pidns-translation -f -e signal=!SIGKILL $@ $args > "$EXP"
+
+	#filter out logs made by the parent process of the pidns test
+	parent_pid="$(tail -n 1 $LOG | cut -d' ' -f1)"
+	grep -E -v "^$parent_pid " "$LOG" > "$OUT"
+	match_diff "$OUT" "$EXP"
+}
+
+test_pidns()
+{
+	#unshare requires root before 3.8 even with CLONE_NEWUSER
+	require_min_kernel_version_or_skip 3.8
+	check_prog unshare
+
+	test_pidns_run_strace "$@"
+
+	#test PID translation when /proc is mounted from an other namespace
+	STRACE="unshare -Urpf $STRACE"
+	test_pidns_run_strace "$@"
+}
+
 check_prog cat
 check_prog rm
 
diff --git a/tests/ioctl_block--pidns-translation.c b/tests/ioctl_block--pidns-translation.c
new file mode 100644
index 00000000..5eed6076
--- /dev/null
+++ b/tests/ioctl_block--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "ioctl_block.c"
diff --git a/tests/ioctl_block--pidns-translation.test b/tests/ioctl_block--pidns-translation.test
new file mode 100755
index 00000000..609296c8
--- /dev/null
+++ b/tests/ioctl_block--pidns-translation.test
@@ -0,0 +1,20 @@
+#!/bin/sh
+#
+# Check ioctl syscall decoding.
+#
+# Copyright (c) 2020 The strace developers.
+# All rights reserved.
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+. "${srcdir=.}/init.sh"
+
+check_prog tail
+check_prog cut
+check_prog grep
+
+run_prog > /dev/null
+run_strace --pidns-translation -f -e signal=none -a16 -e trace=ioctl $@ $args > "$EXP"
+parent_pid="$(tail -n 1 $LOG | cut -d' ' -f1)"
+grep -E -v "^$parent_pid |^ioctl\([012][,<]" "$LOG" > "$OUT"
+match_diff "$OUT" "$EXP"
diff --git a/tests/ioctl_block.c b/tests/ioctl_block.c
index 67fee35c..1ccbd033 100644
--- a/tests/ioctl_block.c
+++ b/tests/ioctl_block.c
@@ -9,7 +9,9 @@
  */
 
 #include "tests.h"
+#include "pidns.h"
 #include <errno.h>
+#include <unistd.h>
 #include <inttypes.h>
 #include <stdio.h>
 #include <string.h>
@@ -41,12 +43,17 @@ static struct xlat_data block_argless[] = {
 #define TEST_NULL_ARG(cmd)						\
 	do {								\
 		ioctl(-1, cmd, 0);					\
+		pidns_print_leader();					\
 		printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n", #cmd);	\
 	} while (0)
 
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	TEST_NULL_ARG(BLKBSZGET);
 	TEST_NULL_ARG(BLKBSZSET);
 	TEST_NULL_ARG(BLKFRAGET);
@@ -91,18 +98,22 @@ main(void)
 #endif
 
 	ioctl(-1, BLKRASET, lmagic);
+	pidns_print_leader();
 	printf("ioctl(-1, BLKRASET, %lu) = -1 EBADF (%m)\n", lmagic);
 
 	ioctl(-1, BLKFRASET, lmagic);
+	pidns_print_leader();
 	printf("ioctl(-1, BLKFRASET, %lu) = -1 EBADF (%m)\n", lmagic);
 
 	TAIL_ALLOC_OBJECT_CONST_PTR(int, val_int);
 	*val_int = magic;
 
 	ioctl(-1, BLKROSET, val_int);
+	pidns_print_leader();
 	printf("ioctl(-1, BLKROSET, [%d]) = -1 EBADF (%m)\n", *val_int);
 
 	ioctl(-1, BLKBSZSET, val_int);
+	pidns_print_leader();
 	printf("ioctl(-1, BLKBSZSET, [%d]) = -1 EBADF (%m)\n", *val_int);
 
 	uint64_t *pair_int64 = tail_alloc(sizeof(*pair_int64) * 2);
@@ -111,18 +122,21 @@ main(void)
 
 #ifdef BLKDISCARD
 	ioctl(-1, BLKDISCARD, pair_int64);
+	pidns_print_leader();
 	printf("ioctl(-1, BLKDISCARD, [%" PRIu64 ", %" PRIu64 "])"
 	       " = -1 EBADF (%m)\n", pair_int64[0], pair_int64[1]);
 #endif
 
 #ifdef BLKSECDISCARD
 	ioctl(-1, BLKSECDISCARD, pair_int64);
+	pidns_print_leader();
 	printf("ioctl(-1, BLKSECDISCARD, [%" PRIu64 ", %" PRIu64 "])"
 	       " = -1 EBADF (%m)\n", pair_int64[0], pair_int64[1]);
 #endif
 
 #ifdef BLKZEROOUT
 	ioctl(-1, BLKZEROOUT, pair_int64);
+	pidns_print_leader();
 	printf("ioctl(-1, BLKZEROOUT, [%" PRIu64 ", %" PRIu64 "])"
 	       " = -1 EBADF (%m)\n", pair_int64[0], pair_int64[1]);
 #endif
@@ -134,6 +148,7 @@ main(void)
 	blkpg->data = (void *) (unsigned long) 0xcafef00dfffffeedULL;
 
 	ioctl(-1, BLKPG, blkpg);
+	pidns_print_leader();
 	printf("ioctl(-1, BLKPG, {op=%s, flags=%d, datalen=%d"
 	       ", data=%#lx}) = -1 EBADF (%m)\n",
 	       "BLKPG_RESIZE_PARTITION", blkpg->flags, blkpg->datalen,
@@ -149,6 +164,7 @@ main(void)
 	blkpg->data = bp;
 
 	ioctl(-1, BLKPG, blkpg);
+	pidns_print_leader();
 	printf("ioctl(-1, BLKPG, {op=%s, flags=%d, datalen=%d"
 	       ", data={start=%lld, length=%lld, pno=%d"
 	       ", devname=\"%.*s\"..., volname=\"%.*s\"...}})"
@@ -162,25 +178,31 @@ main(void)
 #if defined BLKTRACESETUP && defined HAVE_STRUCT_BLK_USER_TRACE_SETUP
 	TAIL_ALLOC_OBJECT_CONST_PTR(struct blk_user_trace_setup, buts);
 	fill_memory(buts, sizeof(*buts));
+	buts->pid = getpid();
 
 	ioctl(-1, BLKTRACESETUP, buts);
+	pidns_print_leader();
 	printf("ioctl(-1, BLKTRACESETUP, {act_mask=%hu, buf_size=%u, buf_nr=%u"
-	       ", start_lba=%" PRI__u64 ", end_lba=%" PRI__u64 ", pid=%d})"
+	       ", start_lba=%" PRI__u64 ", end_lba=%" PRI__u64 ", pid=%d%s})"
 	       " = -1 EBADF (%m)\n",
 	       buts->act_mask, buts->buf_size, buts->buf_nr,
-	       buts->start_lba, buts->end_lba, buts->pid);
+	       buts->start_lba, buts->end_lba, buts->pid,
+	       pidns_pid2str(PT_TGID));
 #endif
 
 	unsigned int i;
 	for (i = 0; i < ARRAY_SIZE(block_argless); ++i) {
 		ioctl(-1, (unsigned long) block_argless[i].val, lmagic);
+		pidns_print_leader();
 		printf("ioctl(-1, %s) = -1 EBADF (%m)\n", block_argless[i].str);
 	}
 
 	ioctl(-1, _IOC(_IOC_READ, 0x12, 0xfe, 0xff), lmagic);
+	pidns_print_leader();
 	printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n",
 	       "_IOC(_IOC_READ, 0x12, 0xfe, 0xff)", lmagic);
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/ioprio--pidns-translation.c b/tests/ioprio--pidns-translation.c
new file mode 100644
index 00000000..bcb49a8b
--- /dev/null
+++ b/tests/ioprio--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "ioprio.c"
diff --git a/tests/ioprio.c b/tests/ioprio.c
index 5e1e1194..f75da7de 100644
--- a/tests/ioprio.c
+++ b/tests/ioprio.c
@@ -9,8 +9,8 @@
  */
 
 #include "tests.h"
-
 #include "scno.h"
+#include "pidns.h"
 
 #if defined(__NR_ioprio_get) && defined(__NR_ioprio_set)
 
@@ -30,12 +30,20 @@ enum {
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	static const kernel_ulong_t bogus_which =
 		(kernel_ulong_t) 0xdeadfacefa57beefULL;
 	static const kernel_ulong_t bogus_who =
 		(kernel_ulong_t) 0xbadc0dedda7a1057ULL;
 	static const kernel_ulong_t bogus_ioprio =
 		(kernel_ulong_t) 0xdec0ded1facefeedULL;
+
+	const int pid = getpid();
+	const int pgid = getpgid(0);
+
 # if !XLAT_RAW
 	static const char * const bogus_ioprio_str =
 		"IOPRIO_PRIO_VALUE(0x7d677 /* IOPRIO_CLASS_??? */, 7917)";
@@ -46,6 +54,7 @@ main(void)
 
 	rc = syscall(__NR_ioprio_get, bogus_which, bogus_who);
 	errstr = sprintrc(rc);
+	pidns_print_leader();
 # if XLAT_RAW
 	printf("ioprio_get(%#x, %d) = %s\n",
 	       (int) bogus_which, (int) bogus_who, errstr);
@@ -54,42 +63,52 @@ main(void)
 	       (int) bogus_which, (int) bogus_who, errstr);
 # endif
 
-	rc = syscall(__NR_ioprio_get, 1, 0);
+	rc = syscall(__NR_ioprio_get, 1, pid);
 	errstr = sprintrc(rc);
+	pidns_print_leader();
+	printf("ioprio_get(");
 # if XLAT_RAW
-	printf("ioprio_get(0x1, 0) = %s\n", errstr);
+	printf("0x1, ");
+# elif XLAT_VERBOSE
+	printf("0x1 /* IOPRIO_WHO_PROCESS */, ");
 # else /* XLAT_ABBREV */
-#  if XLAT_VERBOSE
-	printf("ioprio_get(0x1 /* IOPRIO_WHO_PROCESS */, 0) = %s", errstr);
-#  else
-	printf("ioprio_get(IOPRIO_WHO_PROCESS, 0) = %s", errstr);
-#  endif
+	printf("IOPRIO_WHO_PROCESS, ");
+# endif
+	printf("%d%s) = %s", pid, pidns_pid2str(PT_TGID), errstr);
+# if !XLAT_RAW
 	if (rc >= 0) {
 		printf(" (IOPRIO_PRIO_VALUE(");
 		printxval(ioprio_class, (unsigned int) rc >> 13,
 			  "IOPRIO_CLASS_???");
 		printf(", %u))", (unsigned int) rc & 0x1fff);
 	}
-	puts("");
 # endif
+	puts("");
 
-	rc = syscall(__NR_ioprio_set, 2, 0, 8191);
+	rc = syscall(__NR_ioprio_set, 2, pgid, 8191);
 	errstr = sprintrc(rc);
+	pidns_print_leader();
+	printf("ioprio_set(");
 # if XLAT_RAW
-	printf("ioprio_set(%#x, 0, 8191) = %s\n", 2, errstr);
+	printf("%#x", 2);
 # elif XLAT_VERBOSE
-	printf("ioprio_set(%#x /* IOPRIO_WHO_PGRP */, 0, 8191"
-	       " /* IOPRIO_PRIO_VALUE(0 /* IOPRIO_CLASS_NONE */, 8191) */)"
-	       " = %s\n",
-	       2, errstr);
+	printf("%#x /* IOPRIO_WHO_PGRP */", 2);
 # else /* XLAT_ABBREV */
-	printf("ioprio_set(IOPRIO_WHO_PGRP, 0"
-	       ", IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 8191)) = %s\n",
-	       errstr);
+	printf("IOPRIO_WHO_PGRP");
+# endif
+	printf(", %d%s", pgid, pidns_pid2str(PT_PGID));
+# if XLAT_RAW
+	printf(", 8191)");
+# elif XLAT_VERBOSE
+	printf(", 8191 /* IOPRIO_PRIO_VALUE(0 /* IOPRIO_CLASS_NONE */, 8191) */)");
+# else /* XLAT_ABBREV */
+	printf(", IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 8191))");
 # endif
+	printf(" = %s\n", errstr);
 
 	rc = syscall(__NR_ioprio_set, bogus_which, bogus_who, bogus_ioprio);
 	errstr = sprintrc(rc);
+	pidns_print_leader();
 # if XLAT_RAW
 	printf("ioprio_set(%#x, %d, %d) = %s\n",
 	       (int) bogus_which, (int) bogus_who, (int) bogus_ioprio,
@@ -104,6 +123,7 @@ main(void)
 	       errstr);
 # endif
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 
 	return 0;
diff --git a/tests/kcmp-yY.c b/tests/kcmp-yY.c
new file mode 100644
index 00000000..f54d94cc
--- /dev/null
+++ b/tests/kcmp-yY.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "kcmp-y.c"
diff --git a/tests/kcmp.c b/tests/kcmp.c
index dc5ba9a4..c189d489 100644
--- a/tests/kcmp.c
+++ b/tests/kcmp.c
@@ -9,8 +9,8 @@
  */
 
 #include "tests.h"
-
 #include "scno.h"
+#include "pidns.h"
 
 #ifdef __NR_kcmp
 
@@ -101,7 +101,11 @@ do_kcmp(kernel_ulong_t pid1, kernel_ulong_t pid2, kernel_ulong_t type,
 	rc = syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
 	errstr = sprintrc(rc);
 
-	printf("kcmp(%d, %d, ", (int) pid1, (int) pid2);
+	const char *pid_str = pidns_pid2str(PT_TGID);
+	pidns_print_leader();
+	printf("kcmp(%d%s, %d%s, ",
+		(int) pid1, (int) pid1 == getpid() ? pid_str : "",
+		(int) pid2, (int) pid2 == getpid() ? pid_str : "");
 
 	if (type_str)
 		printf("%s", type_str);
@@ -146,6 +150,10 @@ do_kcmp(kernel_ulong_t pid1, kernel_ulong_t pid2, kernel_ulong_t type,
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	static const kernel_ulong_t bogus_pid1 =
 		(kernel_ulong_t) 0xdeadca75face1057ULL;
 	static const kernel_ulong_t bogus_pid2 =
@@ -221,6 +229,7 @@ main(void)
 			(uintptr_t) slot, 1);
 	}
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 
 	return 0;
diff --git a/tests/kill--pidns-translation.c b/tests/kill--pidns-translation.c
new file mode 100644
index 00000000..4736ca14
--- /dev/null
+++ b/tests/kill--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "kill.c"
diff --git a/tests/kill.c b/tests/kill.c
index f7d9341e..4e639a4f 100644
--- a/tests/kill.c
+++ b/tests/kill.c
@@ -11,6 +11,7 @@
 
 #include "tests.h"
 #include "scno.h"
+#include "pidns.h"
 
 #ifdef __NR_kill
 
@@ -26,6 +27,10 @@ handler(int sig)
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	const struct sigaction act = { .sa_handler = handler };
 	if (sigaction(SIGALRM, &act, NULL))
 		perror_msg_and_fail("sigaction");
@@ -37,18 +42,23 @@ main(void)
 		perror_msg_and_fail("sigprocmask");
 
 	const int pid = getpid();
+	const char *pid_str = pidns_pid2str(PT_TGID);
 	long rc = syscall(__NR_kill, pid, (long) 0xdefaced00000000ULL | SIGALRM);
-	printf("kill(%d, SIGALRM) = %ld\n", pid, rc);
+	pidns_print_leader();
+	printf("kill(%d%s, SIGALRM) = %ld\n", pid, pid_str, rc);
 
 	const long big_pid = (long) 0xfacefeedbadc0dedULL;
 	const long big_sig = (long) 0xdeadbeefcafef00dULL;
 	rc = syscall(__NR_kill, big_pid, big_sig);
+	pidns_print_leader();
 	printf("kill(%d, %d) = %ld %s (%m)\n",
 	       (int) big_pid, (int) big_sig, rc, errno2name());
 
 	rc = syscall(__NR_kill, (long) 0xdefaced00000000ULL | pid, 0);
-	printf("kill(%d, 0) = %ld\n", pid, rc);
+	pidns_print_leader();
+	printf("kill(%d%s, 0) = %ld\n", pid, pid_str, rc);
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/migrate_pages--pidns-translation.c b/tests/migrate_pages--pidns-translation.c
new file mode 100644
index 00000000..ec34938d
--- /dev/null
+++ b/tests/migrate_pages--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "migrate_pages.c"
diff --git a/tests/migrate_pages.c b/tests/migrate_pages.c
index 2dfba49c..eaff1d0a 100644
--- a/tests/migrate_pages.c
+++ b/tests/migrate_pages.c
@@ -10,6 +10,7 @@
 
 #include "tests.h"
 #include "scno.h"
+#include "pidns.h"
 
 #ifdef __NR_migrate_pages
 
@@ -19,11 +20,17 @@
 int
 main(void)
 {
-	const long pid = (long) 0xfacefeedffffffffULL;
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
+	const long pid = (long) 0xfacefeed00000000ULL | getpid();
 	long rc = syscall(__NR_migrate_pages, pid, 0, 0, 0);
-	printf("migrate_pages(%d, 0, NULL, NULL) = %ld %s (%m)\n",
-	       (int) pid, rc, errno2name());
+	pidns_print_leader();
+	printf("migrate_pages(%d%s, 0, NULL, NULL) = %ld %s (%m)\n",
+	       (int) pid, pidns_pid2str(PT_TGID), rc, errno2name());
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/move_pages--pidns-translation.c b/tests/move_pages--pidns-translation.c
new file mode 100644
index 00000000..8498e399
--- /dev/null
+++ b/tests/move_pages--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "move_pages.c"
diff --git a/tests/move_pages.c b/tests/move_pages.c
index e00fd1ac..a63bf894 100644
--- a/tests/move_pages.c
+++ b/tests/move_pages.c
@@ -10,6 +10,7 @@
 
 #include "tests.h"
 #include "scno.h"
+#include "pidns.h"
 
 #ifdef __NR_move_pages
 
@@ -122,15 +123,20 @@ print_status_array(const int *const status, const unsigned long count)
 }
 
 static void
-print_stat_pages(const unsigned long pid, const unsigned long count,
-		 const void **const pages, int *const status)
+print_stat_pages(const unsigned long pid,
+		 const char *pid_str,
+		 const unsigned long count,
+		 const void **const pages,
+		 int *const status)
 {
 	const unsigned long flags = (unsigned long) 0xfacefeed00000002ULL;
 
 	long rc = syscall(__NR_move_pages,
 			  pid, count, pages, NULL, status, flags);
 	const char *errstr = sprintrc(rc);
-	printf("move_pages(%d, %lu, ", (int) pid, count);
+	pidns_print_leader();
+	printf("move_pages(%d%s, %lu, ", (int) pid, pid_str,
+		count);
 	print_page_array(pages, count, 0);
 	printf(", NULL, ");
 	if (rc) {
@@ -152,6 +158,7 @@ print_stat_pages(const unsigned long pid, const unsigned long count,
 
 static void
 print_move_pages(const unsigned long pid,
+		 const char *pid_str,
 		 unsigned long count,
 		 const unsigned int offset,
 		 const void **const pages,
@@ -164,7 +171,9 @@ print_move_pages(const unsigned long pid,
 	long rc = syscall(__NR_move_pages,
 			  pid, count, pages, nodes, status, flags);
 	const char *errstr = sprintrc(rc);
-	printf("move_pages(%d, %lu, ", (int) pid, count);
+	pidns_print_leader();
+	printf("move_pages(%d%s, %lu, ", (int) pid, pid_str,
+		count);
 	print_page_array(pages, count, offset);
 	printf(", ");
 	print_node_array(nodes, count, offset);
@@ -185,8 +194,13 @@ print_move_pages(const unsigned long pid,
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	const unsigned long pid =
 		(unsigned long) 0xfacefeed00000000ULL | getpid();
+	const char *pid_str = pidns_pid2str(PT_TGID);
 	unsigned long count = 1;
 	const unsigned page_size = get_page_size();
 	const void *const page = tail_alloc(page_size);
@@ -195,40 +209,41 @@ main(void)
 	TAIL_ALLOC_OBJECT_VAR_PTR(int, nodes);
 	TAIL_ALLOC_OBJECT_VAR_PTR(int, status);
 
-	print_stat_pages(pid, 0, pages, status);
-	print_move_pages(pid, 0, 0, pages, nodes, status);
-	print_move_pages(pid, 0, 1, pages + 1, nodes + 1, status + 1);
+	print_stat_pages(pid, pid_str, 0, pages, status);
+	print_move_pages(pid, pid_str, 0, 0, pages, nodes, status);
+	print_move_pages(pid, pid_str, 0, 1, pages + 1, nodes + 1, status + 1);
 
 	*pages = page;
-	print_stat_pages(pid, count, pages, status);
+	print_stat_pages(pid, pid_str, count, pages, status);
 	*nodes = 0xdeadbee1;
-	print_move_pages(pid, count, 0, pages, nodes, status);
-	print_move_pages(pid, count, 1, pages, nodes, status);
+	print_move_pages(pid, pid_str, count, 0, pages, nodes, status);
+	print_move_pages(pid, pid_str, count, 1, pages, nodes, status);
 
 	++count;
 	--status;
 	*(--pages) = efault;
-	print_stat_pages(pid, count, pages, status);
+	print_stat_pages(pid, pid_str, count, pages, status);
 	*(--nodes) = 0xdeadbee2;
-	print_move_pages(pid, count, 0, pages, nodes, status);
-	print_move_pages(pid, count, 1, pages, nodes, status);
+	print_move_pages(pid, pid_str, count, 0, pages, nodes, status);
+	print_move_pages(pid, pid_str, count, 1, pages, nodes, status);
 
 	++count;
 	--status;
 	*(--pages) = nodes;
-	print_stat_pages(pid, count, pages, status);
+	print_stat_pages(pid, pid_str, count, pages, status);
 	*(--nodes) = 0xdeadbee3;
-	print_move_pages(pid, count, 0, pages, nodes, status);
-	print_move_pages(pid, count, 1, pages, nodes, status);
+	print_move_pages(pid, pid_str, count, 0, pages, nodes, status);
+	print_move_pages(pid, pid_str, count, 1, pages, nodes, status);
 
 	++count;
 	--status;
 	*(--pages) = status;
-	print_stat_pages(pid, count, pages, status);
+	print_stat_pages(pid, pid_str, count, pages, status);
 	*(--nodes) = 0xdeadbee4;
-	print_move_pages(pid, count, 0, pages, nodes, status);
-	print_move_pages(pid, count, 1, pages, nodes, status);
+	print_move_pages(pid, pid_str, count, 0, pages, nodes, status);
+	print_move_pages(pid, pid_str, count, 1, pages, nodes, status);
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/net-sockaddr--pidns-translation.c b/tests/net-sockaddr--pidns-translation.c
new file mode 100644
index 00000000..ff432bf4
--- /dev/null
+++ b/tests/net-sockaddr--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "net-sockaddr.c"
diff --git a/tests/net-sockaddr.c b/tests/net-sockaddr.c
index 4fc9da6e..4dc04b54 100644
--- a/tests/net-sockaddr.c
+++ b/tests/net-sockaddr.c
@@ -9,6 +9,7 @@
  */
 
 #include "tests.h"
+#include "pidns.h"
 #include <stddef.h>
 #include <stdio.h>
 #include <string.h>
@@ -40,18 +41,21 @@ check_un(void)
 	memset(un->sun_path, '0', sizeof(un->sun_path));
 	unsigned int len = sizeof(*un);
 	int ret = connect(-1, (void *) un, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
 	       ", %u) = %d EBADF (%m)\n",
 	       (int) sizeof(un->sun_path), 0, len, ret);
 
 	un->sun_path[1] = 0;
 	ret = connect(-1, (void *) un, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%u\"}, %u)"
 	       " = %d EBADF (%m)\n", 0, len, ret);
 
 	un->sun_path[0] = 0;
 	un->sun_path[2] = 1;
 	ret = connect(-1, (void *) un, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"\\0\\001%.*u\"}"
 	       ", %u) = %d EBADF (%m)\n",
 	       (int) sizeof(un->sun_path) - 3, 0, len, ret);
@@ -61,12 +65,14 @@ check_un(void)
 	memset(un->sun_path, '0', sizeof(un->sun_path));
 	len = sizeof(*un) + 2;
 	ret = connect(-1, (void *) un, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
 	       ", %u) = %d EBADF (%m)\n",
 	       (int) sizeof(un->sun_path), 0, len, ret);
 
 	un->sun_path[0] = 0;
 	ret = connect(-1, (void *) un, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
 	       ", %u) = %d EBADF (%m)\n",
 	       (int) sizeof(un->sun_path) - 1, 0, len, ret);
@@ -75,18 +81,21 @@ check_un(void)
 	un->sun_family = AF_UNIX;
 	len = sizeof(*un) - 2;
 	ret = connect(-1, (void *) un, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
 	       ", %u) = %d EBADF (%m)\n",
 	       (int) sizeof(un->sun_path) - 2, 0, len, ret);
 
 	un->sun_path[0] = 0;
 	ret = connect(-1, (void *) un, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
 	       ", %u) = %d EBADF (%m)\n",
 	       (int) sizeof(un->sun_path) - 3, 0, len, ret);
 
 	len = sizeof(*un);
 	ret = connect(-1, (void *) un, len);
+	pidns_print_leader();
 	printf("connect(-1, %p, %u) = %d EBADF (%m)\n", un, len, ret);
 
 	un = tail_alloc(sizeof(struct sockaddr_storage));
@@ -94,12 +103,14 @@ check_un(void)
 	memset(un->sun_path, '0', sizeof(un->sun_path));
 	len = sizeof(struct sockaddr_storage) + 1;
 	ret = connect(-1, (void *) un, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
 	       ", %u) = %d EBADF (%m)\n",
 	       (int) sizeof(un->sun_path), 0, len, ret);
 
 	un->sun_path[0] = 0;
 	ret = connect(-1, (void *) un, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
 	       ", %u) = %d EBADF (%m)\n",
 	       (int) sizeof(un->sun_path) - 1, 0, len, ret);
@@ -117,6 +128,7 @@ check_in(void)
 	in->sin_addr.s_addr = inet_addr(h_addr);
 	unsigned int len = sizeof(*in);
 	int ret = connect(-1, (void *) in, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_INET, sin_port=htons(%hu)"
 	       ", sin_addr=inet_addr(\"%s\")}, %u) = %d EBADF (%m)\n",
 	       h_port, h_addr, len, ret);
@@ -127,6 +139,7 @@ check_in(void)
 	in->sin_addr.s_addr = inet_addr(h_addr);
 	len = sizeof(*in) + 4;
 	ret = connect(-1, (void *) in, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_INET, sin_port=htons(%hu)"
 	       ", sin_addr=inet_addr(\"%s\")}, %u) = %d EBADF (%m)\n",
 	       h_port, h_addr, len, ret);
@@ -137,6 +150,7 @@ check_in(void)
 	in->sin_addr.s_addr = 0;
 	len = sizeof(*in) - 4;
 	ret = connect(-1, (void *) in, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_INET, sa_data=\"%s\"}, %u)"
 	       " = %d EBADF (%m)\n",
 	       "\\0\\0\\0\\0\\0\\0\\377\\377\\377\\377",
@@ -144,6 +158,7 @@ check_in(void)
 
 	len = sizeof(*in);
 	ret = connect(-1, (void *) in, len);
+	pidns_print_leader();
 	printf("connect(-1, %p, %u) = %d EBADF (%m)\n", in, len, ret);
 }
 
@@ -155,6 +170,7 @@ check_in6_linklocal(struct sockaddr_in6 *const in6, const char *const h_addr)
 	in6->sin6_scope_id = 0xfacefeed;
 	unsigned int len = sizeof(*in6);
 	int ret = connect(-1, (void *) in6, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
 	       ", sin6_flowinfo=htonl(%u)"
 	       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
@@ -166,7 +182,8 @@ check_in6_linklocal(struct sockaddr_in6 *const in6, const char *const h_addr)
 	in6->sin6_scope_id = ifindex_lo();
 	if (in6->sin6_scope_id) {
 		ret = connect(-1, (void *) in6, len);
-		printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
+		pidns_print_leader();
+	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
 		       ", sin6_flowinfo=htonl(%u)"
 		       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
 		       ", sin6_scope_id=%s}, %u)"
@@ -191,6 +208,7 @@ check_in6(void)
 	in6->sin6_scope_id = 0xfacefeed;
 	unsigned int len = sizeof(*in6);
 	int ret = connect(-1, (void *) in6, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
 	       ", sin6_flowinfo=htonl(%u)"
 	       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
@@ -209,6 +227,7 @@ check_in6(void)
 	in6->sin6_scope_id = 0xfacefeed;
 	len = sizeof(*in6) + 4;
 	ret = connect(-1, (void *) in6, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
 	       ", sin6_flowinfo=htonl(%u)"
 	       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
@@ -223,6 +242,7 @@ check_in6(void)
 	inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
 	len = sizeof(*in6) - sizeof(in6->sin6_scope_id);
 	ret = connect(-1, (void *) in6, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
 	       ", sin6_flowinfo=htonl(%u)"
 	       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)}, %u)"
@@ -236,6 +256,7 @@ check_in6(void)
 	memset(&in6->sin6_addr, '0', sizeof(in6->sin6_addr) - 4);
 	len = sizeof(*in6) - sizeof(in6->sin6_scope_id) - 4;
 	ret = connect(-1, (void *) in6, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_INET6"
 	       ", sa_data=\"\\0\\0\\0\\0\\0\\000%.*u\"}, %u)"
 	       " = %d EBADF (%m)\n",
@@ -244,6 +265,7 @@ check_in6(void)
 
 	len = sizeof(*in6) - sizeof(in6->sin6_scope_id);
 	ret = connect(-1, (void *) in6, len);
+	pidns_print_leader();
 	printf("connect(-1, %p, %u) = %d EBADF (%m)\n", in6, len, ret);
 }
 
@@ -262,6 +284,7 @@ check_ipx(void)
 	void *ipx = tail_memdup(&c_ipx, sizeof(c_ipx));
 	unsigned int len = sizeof(c_ipx);
 	int ret = connect(-1, ipx, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_IPX, sipx_port=htons(%u)"
 	       ", sipx_network=htonl(%#x)"
 	       ", sipx_node=[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
@@ -316,18 +339,21 @@ check_ax25(void)
 	fill_memory(sax, size);
 	sax->fsa_ax25.sax25_family = AF_AX25;
 	rc = connect(-1, sax_void, sizeof(struct sockaddr_ax25) - 1);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_AX25, sa_data=\"\\202\\203\\204\\205"
 	       "\\206\\207\\210\\211\\212\\213\\214\\215\\216\"}, %zu) = %s\n",
 	       sizeof(struct sockaddr_ax25) - 1, sprintrc(rc));
 
 	memcpy(sax, &ax25, sizeof(ax25));
 	rc = connect(-1, sax_void, sizeof(struct sockaddr_ax25));
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_AX25, fsa_ax25={sax25_call=VALID-13"
 	       ", sax25_ndigis=8}, fsa_digipeater=[/* ??? */]}, %zu) = %s\n",
 	       sizeof(struct sockaddr_ax25), sprintrc(rc));
 
 	sax->fsa_ax25.sax25_ndigis = 0;
 	rc = connect(-1, sax_void, sizeof(struct sockaddr_ax25));
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_AX25, sax25_call=VALID-13"
 	       ", sax25_ndigis=0}, %zu) = %s\n",
 	       sizeof(struct sockaddr_ax25), sprintrc(rc));
@@ -335,6 +361,7 @@ check_ax25(void)
 	sax->fsa_ax25.sax25_ndigis = 8;
 	size = sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 3 + 1;
 	rc = connect(-1, sax_void, size);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_AX25, fsa_ax25={sax25_call=VALID-13"
 	       ", sax25_ndigis=8}, fsa_digipeater"
 	       "=[{ax25_call=\"\\xa6\\xa0\\x82\\x40\\x86\\x8a\\x00\""
@@ -348,6 +375,7 @@ check_ax25(void)
 	sax->fsa_digipeater[2].ax25_call[6] = 0x4;
 	size = sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 4;
 	rc = connect(-1, sax_void, size);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_AX25, fsa_ax25={sax25_call=VALID-13"
 	       ", sax25_ndigis=8}, fsa_digipeater"
 	       "=[{ax25_call=\"\\xa6\\xa0\\x82\\x40\\x86\\x8a\\x00\""
@@ -365,7 +393,8 @@ check_ax25(void)
 	for (size_t i = 0; i < 3; i++) {
 		size = sizeof(ax25) + sizeof(ax25_address) * (i / 2);
 		rc = connect(-1, sax_void, size);
-		printf("connect(-1, {sa_family=AF_AX25"
+		pidns_print_leader();
+	printf("connect(-1, {sa_family=AF_AX25"
 		       ", fsa_ax25={sax25_call=VALID-13, sax25_ndigis=%d}"
 		       ", fsa_digipeater=[VALID2-7, OK-15, %s /* FINE-2 */"
 		       ", {ax25_call=\"\\xe6\\xda\\xc2\\xd8\\xd8\\xe6\\x12\""
@@ -427,13 +456,15 @@ check_x25(void)
 	long rc;
 
 	rc = connect(-1, x25_void, sizeof(c_x25) - 1);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_X25"
 	       ", sa_data=\"0123456789abcde\"}, %zu) = %s\n",
 	       sizeof(c_x25) - 1, sprintrc(rc));
 
 	for (size_t i = 0; i < 2; i++) {
 		rc = connect(-1, x25_void, sizeof(c_x25) + i);
-		printf("connect(-1, {sa_family=AF_X25"
+		pidns_print_leader();
+	printf("connect(-1, {sa_family=AF_X25"
 		       ", sx25_addr={x25_addr=\"0123456789abcde\"...}"
 		       "}, %zu) = %s\n",
 		       sizeof(c_x25) + i, sprintrc(rc));
@@ -442,6 +473,7 @@ check_x25(void)
 	struct sockaddr_x25 *const x25 = x25_void;
 	x25->sx25_addr.x25_addr[10] = '\0';
 	rc = connect(-1, x25_void, sizeof(c_x25));
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_X25"
 	       ", sx25_addr={x25_addr=\"0123456789\"}"
 	       "}, %zu) = %s\n",
@@ -457,19 +489,21 @@ check_nl(void)
 	nl->nl_groups = 0xfacefeed;
 	unsigned int len = sizeof(*nl);
 	int ret = connect(-1, (void *) nl, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_NETLINK, nl_pid=%d"
 	       ", nl_groups=%#08x}, %u) = %d EBADF (%m)\n",
 	       nl->nl_pid, nl->nl_groups, len, ret);
 
 	nl = ((void *) nl) - 4;
 	nl->nl_family = AF_NETLINK;
-	nl->nl_pid = 1234567890;
+	nl->nl_pid = getpid();
 	nl->nl_groups = 0xfacefeed;
 	len = sizeof(*nl) + 4;
 	ret = connect(-1, (void *) nl, len);
-	printf("connect(-1, {sa_family=AF_NETLINK, nl_pid=%d"
+	pidns_print_leader();
+	printf("connect(-1, {sa_family=AF_NETLINK, nl_pid=%d%s"
 	       ", nl_groups=%#08x}, %u) = %d EBADF (%m)\n",
-	       nl->nl_pid, nl->nl_groups, len, ret);
+	       nl->nl_pid, pidns_pid2str(PT_TGID), nl->nl_groups, len, ret);
 }
 
 static void
@@ -487,6 +521,7 @@ check_ll(void)
 	void *ll = tail_memdup(&c_ll, sizeof(c_ll));
 	unsigned int len = sizeof(c_ll);
 	int ret = connect(-1, ll, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_PACKET"
 	       ", sll_protocol=htons(ETH_P_ALL)"
 	       ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
@@ -502,6 +537,7 @@ check_ll(void)
 
 	((struct sockaddr_ll *) ll)->sll_halen++;
 	ret = connect(-1, ll, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_PACKET"
 	       ", sll_protocol=htons(ETH_P_ALL)"
 	       ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
@@ -517,6 +553,7 @@ check_ll(void)
 
 	((struct sockaddr_ll *) ll)->sll_halen = 0;
 	ret = connect(-1, ll, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_PACKET"
 	       ", sll_protocol=htons(ETH_P_ALL)"
 	       ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
@@ -526,7 +563,8 @@ check_ll(void)
 	((struct sockaddr_ll *) ll)->sll_ifindex = ifindex_lo();
 	if (((struct sockaddr_ll *) ll)->sll_ifindex) {
 		ret = connect(-1, ll, len);
-		printf("connect(-1, {sa_family=AF_PACKET"
+	pidns_print_leader();
+	printf("connect(-1, {sa_family=AF_PACKET"
 		       ", sll_protocol=htons(ETH_P_ALL)"
 		       ", sll_ifindex=%s"
 		       ", sll_hatype=ARPHRD_ETHER"
@@ -549,11 +587,13 @@ check_hci(void)
 	unsigned int len = sizeof(*hci);
 
 	int ret = connect(-1, (void *) hci, 4);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_BLUETOOTH, hci_dev=htobs(%hu)"
 	       "}, 4) = %d EBADF (%m)\n",
 	       h_port, ret);
 
 	ret = connect(-1, (void *) hci, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_BLUETOOTH, hci_dev=htobs(%hu)"
 # ifdef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL
 	       ", hci_channel=HCI_CHANNEL_RAW"
@@ -572,6 +612,7 @@ check_sco(void)
 	void *sco = tail_memdup(&c_sco, sizeof(c_sco));
 	unsigned int len = sizeof(c_sco);
 	int ret = connect(-1, sco, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_BLUETOOTH"
 	       ", sco_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
 	       "}, %u) = %d EBADF (%m)\n",
@@ -592,6 +633,7 @@ check_rc(void)
 	void *rc = tail_memdup(&c_rc, sizeof(c_rc));
 	unsigned int len = sizeof(c_rc);
 	int ret = connect(-1, rc, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_BLUETOOTH"
 	       ", rc_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
 	       ", rc_channel=%u}, %u) = %d EBADF (%m)\n",
@@ -619,6 +661,7 @@ check_l2(void)
 	unsigned int len = sizeof(c_l2);
 
 	int ret = connect(-1, l2, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_BLUETOOTH"
 	       ", l2_psm=htobs(L2CAP_PSM_DYN_START + %hu)"
 	       ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
@@ -640,6 +683,7 @@ check_l2(void)
 # endif
 	memcpy(l2, &c_l2, sizeof(c_l2));
 	ret = connect(-1, l2, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_BLUETOOTH"
 	       ", l2_psm=htobs(L2CAP_PSM_SDP)"
 	       ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
@@ -660,6 +704,7 @@ check_l2(void)
 # endif
 	memcpy(l2, &c_l2, sizeof(c_l2));
 	ret = connect(-1, l2, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_BLUETOOTH"
 	       ", l2_psm=htobs(0xbad /* L2CAP_PSM_??? */)"
 	       ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
@@ -677,6 +722,7 @@ check_l2(void)
 	c_l2.l2_cid = htobs(0xffff);
 	memcpy(l2, &c_l2, 12);
 	ret = connect(-1, l2, 12);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_BLUETOOTH"
 	       ", l2_psm=htobs(L2CAP_PSM_AUTO_END)"
 	       ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
@@ -700,6 +746,7 @@ check_raw(void)
 	u.sa->sa_family = 0xff;
 	unsigned int len = sizeof(*u.st) + 8;
 	int ret = connect(-1, (void *) u.st, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=%#x /* AF_??? */, sa_data=\"%.*u\"}"
 	       ", %u) = %d EBADF (%m)\n", u.sa->sa_family,
 	       (int) (sizeof(*u.st) - sizeof(u.sa->sa_family)), 0, len, ret);
@@ -707,11 +754,13 @@ check_raw(void)
 	u.sa->sa_family = 0;
 	len = sizeof(u.sa->sa_family) + 1;
 	ret = connect(-1, (void *) u.st, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_UNSPEC, sa_data=\"0\"}, %u)"
 	       " = %d EBADF (%m)\n", len, ret);
 
 	u.sa->sa_family = AF_BLUETOOTH;
 	ret = connect(-1, (void *) u.st, len);
+	pidns_print_leader();
 	printf("connect(-1, {sa_family=AF_BLUETOOTH, sa_data=\"0\"}, %u)"
 	       " = %d EBADF (%m)\n", len, ret);
 }
@@ -719,6 +768,10 @@ check_raw(void)
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	check_un();
 	check_in();
 	check_in6();
@@ -735,6 +788,7 @@ main(void)
 #endif
 	check_raw();
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/netlink_audit--pidns-translation.c b/tests/netlink_audit--pidns-translation.c
new file mode 100644
index 00000000..e08f9168
--- /dev/null
+++ b/tests/netlink_audit--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "netlink_audit.c"
diff --git a/tests/netlink_audit--pidns-translation.test b/tests/netlink_audit--pidns-translation.test
new file mode 100755
index 00000000..fbc32435
--- /dev/null
+++ b/tests/netlink_audit--pidns-translation.test
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# Check decoding of NETLINK_SOCK_DIAG protocol
+#
+# Copyright (c) 2020 The strace developers.
+# All rights reserved.
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+. "${srcdir=.}/init.sh"
+
+run_prog ../netlink_netlink_diag
+test_pidns -e trace=sendto "$@"
diff --git a/tests/netlink_audit.c b/tests/netlink_audit.c
index eba609a1..719e4dbf 100644
--- a/tests/netlink_audit.c
+++ b/tests/netlink_audit.c
@@ -7,6 +7,7 @@
  */
 
 #include "tests.h"
+#include "pidns.h"
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
@@ -17,18 +18,25 @@
 static void
 test_nlmsg_type(const int fd)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	long rc;
 	struct nlmsghdr nlh = {
 		.nlmsg_len = sizeof(nlh),
 		.nlmsg_type = AUDIT_GET,
 		.nlmsg_flags = NLM_F_REQUEST,
+		.nlmsg_pid = getpid(),
 	};
 
 	rc = sendto(fd, &nlh, sizeof(nlh), MSG_DONTWAIT, NULL, 0);
+	pidns_print_leader();
 	printf("sendto(%d, {len=%u, type=AUDIT_GET"
-	       ", flags=NLM_F_REQUEST, seq=0, pid=0}"
+	       ", flags=NLM_F_REQUEST, seq=0, pid=%d%s}"
 	       ", %u, MSG_DONTWAIT, NULL, 0) = %s\n",
-	       fd, nlh.nlmsg_len, (unsigned) sizeof(nlh), sprintrc(rc));
+	       fd, nlh.nlmsg_len, nlh.nlmsg_pid, pidns_pid2str(PT_TGID),
+	       (unsigned) sizeof(nlh), sprintrc(rc));
 }
 
 int main(void)
@@ -39,6 +47,7 @@ int main(void)
 
 	test_nlmsg_type(fd);
 
+	pidns_print_leader();
 	printf("+++ exited with 0 +++\n");
 
 	return 0;
diff --git a/tests/pidfd_open--pidns-translation.c b/tests/pidfd_open--pidns-translation.c
new file mode 100644
index 00000000..c38e37a8
--- /dev/null
+++ b/tests/pidfd_open--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "pidfd_open.c"
diff --git a/tests/pidfd_open.c b/tests/pidfd_open.c
index 5860adde..82e442c6 100644
--- a/tests/pidfd_open.c
+++ b/tests/pidfd_open.c
@@ -10,6 +10,7 @@
 
 #include "tests.h"
 #include "scno.h"
+#include "pidns.h"
 
 #ifdef __NR_pidfd_open
 
@@ -37,6 +38,10 @@ k_pidfd_open(const unsigned int pid, const unsigned int flags)
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 # if defined PATH_TRACING || defined PRINT_PATHS
 	skip_if_unavailable("/proc/self/fd/");
 # endif
@@ -50,16 +55,19 @@ main(void)
 
 	k_pidfd_open(0, 0);
 # ifndef PATH_TRACING
+	pidns_print_leader();
 	printf("pidfd_open(0, 0) = %s\n", errstr);
 # endif
 
 	k_pidfd_open(-1U, 0);
 # ifndef PATH_TRACING
+	pidns_print_leader();
 	printf("pidfd_open(-1, 0) = %s\n", errstr);
 # endif
 
 	k_pidfd_open(0, -1U);
 # ifndef PATH_TRACING
+	pidns_print_leader();
 	printf("pidfd_open(0, %#x) = %s\n", -1U, errstr);
 # endif
 
@@ -68,7 +76,10 @@ main(void)
 
 	k_pidfd_open(pid, flags);
 # ifndef PATH_TRACING
-	printf("pidfd_open(%d, %#x) = %s\n", pid, flags, errstr);
+	const char *pid_str = pidns_pid2str(PT_TGID);
+	pidns_print_leader();
+	printf("pidfd_open(%d%s, %#x) = %s\n",
+		pid, pid_str, flags, errstr);
 # endif
 
 # ifdef PRINT_PATHS
@@ -80,17 +91,19 @@ main(void)
 # endif
 
 # ifndef PATH_TRACING
-	printf("pidfd_open(%d, 0) = "
+	pidns_print_leader();
+	printf("pidfd_open(%d%s, 0) = "
 #  if defined PRINT_PIDFD
-	       "%ld<pid:%d>\n", pid, rc, pid
+	       "%ld<pid:%d>\n", pid, pid_str, rc, pid
 #  elif defined PRINT_PATHS
-	       "%ld<anon_inode:[pidfd]>\n", pid, rc
+	       "%ld<anon_inode:[pidfd]>\n", pid, pid_str, rc
 #  else
-	       "%s\n", pid, errstr
+	       "%s\n", pid, pid_str, errstr
 #  endif
 	       );
 # endif
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/pidfd_send_signal--pidns-translation.c b/tests/pidfd_send_signal--pidns-translation.c
new file mode 100644
index 00000000..b04f10f5
--- /dev/null
+++ b/tests/pidfd_send_signal--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "pidfd_send_signal.c"
diff --git a/tests/pidfd_send_signal.c b/tests/pidfd_send_signal.c
index 669bc67c..9d9be8b8 100644
--- a/tests/pidfd_send_signal.c
+++ b/tests/pidfd_send_signal.c
@@ -10,6 +10,7 @@
 #include "tests.h"
 #include <unistd.h>
 #include "scno.h"
+#include "pidns.h"
 
 #ifdef __NR_pidfd_send_signal
 
@@ -36,6 +37,10 @@ sys_pidfd_send_signal(int pidfd, int sig, const void *info, int flags)
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	static const char null_path[] = "/dev/null";
 
 	int fd = open(null_path, O_RDONLY);
@@ -46,19 +51,23 @@ main(void)
 	const void *esi = (const void *) si + 1;
 
 	sys_pidfd_send_signal(fd, SIGUSR1, esi, 0);
+	pidns_print_leader();
 	printf("pidfd_send_signal(%d, SIGUSR1, %p, 0) = %s\n",
 	       fd, esi, errstr);
 
 	si->si_signo = SIGUSR1;
 	si->si_code = SI_QUEUE;
+	si->si_pid = getpid();
 
 	sys_pidfd_send_signal(fd, SIGUSR2, si, -1);
+	pidns_print_leader();
 	printf("pidfd_send_signal(%d, SIGUSR2, {si_signo=SIGUSR1"
-	       ", si_code=SI_QUEUE, si_errno=%u, si_pid=%d, si_uid=%d"
+	       ", si_code=SI_QUEUE, si_errno=%u, si_pid=%d%s, si_uid=%d"
 	       ", si_value={int=%d, ptr=%p}}, %#x) = %s\n",
-	       fd, si->si_errno, si->si_pid, si->si_uid, si->si_int, si->si_ptr,
-	       -1, errstr);
+	       fd, si->si_errno, si->si_pid, pidns_pid2str(PT_TGID), si->si_uid,
+	       si->si_int, si->si_ptr, -1, errstr);
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/pidns.c b/tests/pidns.c
new file mode 100644
index 00000000..4e310a70
--- /dev/null
+++ b/tests/pidns.c
@@ -0,0 +1,162 @@
+/*
+ * Testing framework for PID namespace translation
+ *
+ * Copyright (c) 2020 Ákos Uzonyi <uzonyi.akos at gmail.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+#include "tests.h"
+#include "pidns.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <linux/sched.h>
+
+bool pidns_translation = false;
+bool pidns_unshared = false;
+
+/* Our PIDs in strace's namespace */
+pid_t pidns_strace_ids[PT_COUNT];
+
+void
+pidns_print_leader(void)
+{
+	if (pidns_translation)
+		printf("%-5d ", pidns_strace_ids[PT_TID]);
+}
+
+const char *
+pidns_pid2str(enum pid_type type)
+{
+	static const char format[] = " /* %d in strace's PID NS */";
+	static char buf[PT_COUNT][sizeof(format) + sizeof(int)];
+
+	if (type < 0 || type >= PT_COUNT)
+		return "";
+
+	if (!pidns_unshared || !pidns_strace_ids[type])
+		return "";
+
+	snprintf(buf[type], sizeof(buf[type]), format, pidns_strace_ids[type]);
+	return buf[type];
+}
+
+static pid_t
+pidns_fork(int *strace_ids_pipe, pid_t pgid, bool new_sid)
+{
+	if (pipe(strace_ids_pipe) < 0)
+		perror_msg_and_fail("pipe");
+
+	fflush(stdout);
+	pid_t pid = fork();
+	if (pid < 0)
+		perror_msg_and_fail("fork");
+	if (!pid)
+		return 0;
+
+	pidns_strace_ids[PT_TID] = pid;
+	pidns_strace_ids[PT_TGID] = pid;
+	pidns_strace_ids[PT_PGID] = 0;
+	pidns_strace_ids[PT_SID] = 0;
+
+	if (!pgid)
+		pgid = pid;
+
+	if (pgid > 0) {
+		if (setpgid(pid, pgid) < 0)
+			perror_msg_and_fail("setpgid");
+
+		pidns_strace_ids[PT_PGID] = pgid;
+	}
+
+	/* Reap group leader to test PGID decoding */
+	if (pgid > 0 && pgid != pid) {
+		int ret = waitpid(pgid, NULL, WNOHANG);
+		if (ret < 0)
+			perror_msg_and_fail("wait");
+		if (!ret)
+			error_msg_and_fail("could not reap group leader");
+	}
+
+	if (new_sid) {
+		pidns_strace_ids[PT_SID] = pid;
+		pidns_strace_ids[PT_PGID] = pid;
+	}
+
+	if (write(strace_ids_pipe[1], pidns_strace_ids,
+	    sizeof(pidns_strace_ids)) < 0)
+		perror_msg_and_fail("write");
+	close(strace_ids_pipe[0]);
+	close(strace_ids_pipe[1]);
+
+	/* WNOWAIT: leave the zombie, to be able to use it as a process group */
+	siginfo_t siginfo;
+	if (waitid(P_PID, pid, &siginfo, WEXITED | WNOWAIT) < 0)
+		perror_msg_and_fail("wait");
+	if (siginfo.si_code != CLD_EXITED || siginfo.si_status)
+		error_msg_and_fail("child terminated with nonzero exit status");
+
+	return pid;
+}
+
+void
+pidns_test_init(void)
+{
+	pidns_translation = true;
+
+	int strace_ids_pipe[2];
+
+	if (!pidns_fork(strace_ids_pipe, -1, false))
+		goto pidns_test_init_run_test;
+
+	/* Unshare user namespace too, so we do not need to be root */
+	if (unshare(CLONE_NEWUSER | CLONE_NEWPID) < 0)
+		perror_msg_and_fail("unshare");
+
+	pidns_unshared = true;
+
+	/* Create sleeping process to keep PID namespace alive */
+	pid_t pause_pid = fork();
+	if (!pause_pid) {
+		pause();
+		_exit(0);
+	}
+
+	if (!pidns_fork(strace_ids_pipe, -1, false))
+		goto pidns_test_init_run_test;
+
+	if (!pidns_fork(strace_ids_pipe, -1, true))
+		goto pidns_test_init_run_test;
+
+	pid_t pgid;
+	if (!(pgid = pidns_fork(strace_ids_pipe, 0, false)))
+		goto pidns_test_init_run_test;
+
+	if (!pidns_fork(strace_ids_pipe, pgid, false))
+		goto pidns_test_init_run_test;
+
+	kill(pause_pid, SIGKILL);
+	while (wait(NULL) > 0);
+	if (errno != ECHILD)
+		perror_msg_and_fail("wait");
+
+	exit(0);
+
+pidns_test_init_run_test:
+	if (read(strace_ids_pipe[0], pidns_strace_ids,
+	    sizeof(pidns_strace_ids)) < 0)
+		perror_msg_and_fail("read");
+	close(strace_ids_pipe[0]);
+	close(strace_ids_pipe[1]);
+
+	if (pidns_strace_ids[PT_SID])
+		setsid();
+}
diff --git a/tests/pidns.h b/tests/pidns.h
new file mode 100644
index 00000000..a24d0fff
--- /dev/null
+++ b/tests/pidns.h
@@ -0,0 +1,41 @@
+/*
+ * Test PID namespace translation
+ *
+ * Copyright (c) 2020 Ákos Uzonyi <uzonyi.akos at gmail.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+#ifndef STRACE_PIDNS_H
+#define STRACE_PIDNS_H
+
+#include <sys/types.h>
+
+enum pid_type {
+	PT_TID,
+	PT_TGID,
+	PT_PGID,
+	PT_SID,
+
+	PT_COUNT,
+	PT_NONE = -1
+};
+
+/* Prints leader (process tid) if pidns_test_init was called */
+void pidns_print_leader(void);
+
+/*
+ * Returns a static buffer containing the translation of our PID.
+ */
+const char *pidns_pid2str(enum pid_type type);
+
+/**
+ * Init pidns testing.
+ *
+ * Should be called at the beginning of the test's main function
+ *
+ * This function returns from a of child process that is in a new PID namespace.
+ */
+void pidns_test_init(void);
+
+#endif
\ No newline at end of file
diff --git a/tests/prlimit64--pidns-translation.c b/tests/prlimit64--pidns-translation.c
new file mode 100644
index 00000000..3972de66
--- /dev/null
+++ b/tests/prlimit64--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "prlimit64.c"
diff --git a/tests/prlimit64.c b/tests/prlimit64.c
index 34201a2b..aabd0475 100644
--- a/tests/prlimit64.c
+++ b/tests/prlimit64.c
@@ -19,6 +19,7 @@
 # include <sys/resource.h>
 # include <unistd.h>
 
+# include "pidns.h"
 # include "xlat.h"
 # include "xlat/resources.h"
 
@@ -42,8 +43,13 @@ sprint_rlim(uint64_t lim)
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	unsigned long pid =
 		(unsigned long) 0xdefaced00000000ULL | (unsigned) getpid();
+	const char *pid_str = pidns_pid2str(PT_TGID);
 	uint64_t *const rlimit = tail_alloc(sizeof(*rlimit) * 2);
 	const struct xlat_data *xlat;
 	size_t i = 0;
@@ -54,18 +60,23 @@ main(void)
 
 		unsigned long res = 0xfacefeed00000000ULL | xlat->val;
 		long rc = syscall(__NR_prlimit64, pid, res, 0, rlimit);
+		pidns_print_leader();
 		if (rc)
-			printf("prlimit64(%d, %s, NULL, %p) = %ld %s (%m)\n",
-			       (unsigned) pid, xlat->str, rlimit,
+			printf("prlimit64(%d%s, %s, NULL, %p) ="
+				     " %ld %s (%m)\n",
+			       (unsigned) pid, pid_str,
+			       xlat->str, rlimit,
 			       rc, errno2name());
 		else
-			printf("prlimit64(%d, %s, NULL"
+			printf("prlimit64(%d%s, %s, NULL"
 			       ", {rlim_cur=%s, rlim_max=%s}) = 0\n",
-			       (unsigned) pid, xlat->str,
+			       (unsigned) pid, pid_str,
+			       xlat->str,
 			       sprint_rlim(rlimit[0]),
 			       sprint_rlim(rlimit[1]));
 	}
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/process_vm_readv--pidns-translation.c b/tests/process_vm_readv--pidns-translation.c
new file mode 100644
index 00000000..0db29ca2
--- /dev/null
+++ b/tests/process_vm_readv--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "process_vm_readv.c"
diff --git a/tests/process_vm_readv_writev.c b/tests/process_vm_readv_writev.c
index 9309135a..9efa7a7d 100644
--- a/tests/process_vm_readv_writev.c
+++ b/tests/process_vm_readv_writev.c
@@ -12,6 +12,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/uio.h>
+#include "pidns.h"
 
 #if OP_WR
 # define in_iovec  rmt_iovec
@@ -121,7 +122,7 @@ print_iov(const struct iovec *iov, const void *arg_ptr, long rc)
 }
 
 static void
-do_call(kernel_ulong_t pid,
+do_call(kernel_ulong_t pid, enum pid_type pid_type,
 	kernel_ulong_t local_iov, const char *local_arg,
 	kernel_ulong_t liovcnt,
 	kernel_ulong_t remote_iov, const char *remote_arg,
@@ -135,7 +136,8 @@ do_call(kernel_ulong_t pid,
 		flags);
 	errstr = sprintrc(rc);
 
-	printf("%s(%d, ", OP_STR, (int) pid);
+	pidns_print_leader();
+	printf("%s(%d%s, ", OP_STR, (int) pid, pidns_pid2str(pid_type));
 
 	if (pr_iov)
 		pr_iov((const struct iovec *) (uintptr_t) local_iov, local_arg,
@@ -164,6 +166,10 @@ ptr_cast(void *ptr)
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	enum {
 		SIZE_11 = 2,
 		SIZE_12 = 3,
@@ -243,18 +249,18 @@ main(void)
 	fill_memory_ex(data2_out, SIZE_2, SEGM2_BASE, SIZE_2);
 
 
-	do_call(bogus_pid, (kernel_ulong_t) (uintptr_t) ARG_STR(NULL),
+	do_call(bogus_pid, PT_NONE, (kernel_ulong_t) (uintptr_t) ARG_STR(NULL),
 		bogus_iovcnt1, (kernel_ulong_t) (uintptr_t) ARG_STR(NULL),
 		bogus_iovcnt2, bogus_flags, NULL);
 
-	do_call(my_pid, ptr_cast(bogus_iov + ARRAY_SIZE(bogus_iovec)),
+	do_call(my_pid, PT_TGID, ptr_cast(bogus_iov + ARRAY_SIZE(bogus_iovec)),
 		"[]", 0, ptr_cast(in_iov + ARRAY_SIZE(in_iovec)), "[]",
 		0, 0, NULL);
-	do_call(my_pid, ptr_cast(bogus_iov + ARRAY_SIZE(bogus_iovec)), NULL,
-		bogus_iovcnt1, ptr_cast(in_iov + ARRAY_SIZE(in_iovec)), NULL,
-		bogus_iovcnt2, 0, print_iov);
+	do_call(my_pid, PT_TGID, ptr_cast(bogus_iov + ARRAY_SIZE(bogus_iovec)),
+		NULL, bogus_iovcnt1, ptr_cast(in_iov + ARRAY_SIZE(in_iovec)),
+		NULL, bogus_iovcnt2, 0, print_iov);
 
-	do_call(my_pid, ptr_cast(bogus_iov), (char *) &bogus_arg,
+	do_call(my_pid, PT_TGID, ptr_cast(bogus_iov), (char *) &bogus_arg,
 		ARRAY_SIZE(bogus_iovec), ptr_cast(rmt_iov + 2),
 		(char *) &rmt_arg_cut, ARRAY_SIZE(rmt_iovec) - 2, 0, print_iov);
 
@@ -263,7 +269,7 @@ main(void)
 	lcl_arg_cut.check_rc = 1;
 #endif
 
-	do_call(my_pid, ptr_cast(lcl_iov + 2), (char *) &lcl_arg_cut,
+	do_call(my_pid, PT_TGID, ptr_cast(lcl_iov + 2), (char *) &lcl_arg_cut,
 		ARRAY_SIZE(lcl_iovec) - 1, ptr_cast(bogus_iov + 2),
 		(char *) &bogus_arg_cut, ARRAY_SIZE(bogus_iovec) - 1, 0,
 		print_iov);
@@ -273,15 +279,16 @@ main(void)
 	rmt_arg_cut.addr_term = 1;
 	rmt_arg_cut.count = 5;
 
-	do_call(my_pid, ptr_cast(lcl_iov + 2), (char *) &lcl_arg_cut,
+	do_call(my_pid, PT_TGID, ptr_cast(lcl_iov + 2), (char *) &lcl_arg_cut,
 		ARRAY_SIZE(lcl_iovec) - 2, ptr_cast(rmt_iov + 1),
 		(char *) &rmt_arg_cut, ARRAY_SIZE(rmt_iovec), 0, print_iov);
 
 	/* Correct call */
-	do_call(my_pid, ptr_cast(lcl_iov), (char *) &lcl_arg,
+	do_call(my_pid, PT_TGID, ptr_cast(lcl_iov), (char *) &lcl_arg,
 		ARRAY_SIZE(lcl_iovec), ptr_cast(rmt_iov), (char *) &rmt_arg,
 		ARRAY_SIZE(rmt_iovec), 0, print_iov);
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 
 	return 0;
diff --git a/tests/process_vm_writev--pidns-translation.c b/tests/process_vm_writev--pidns-translation.c
new file mode 100644
index 00000000..9ba6a39b
--- /dev/null
+++ b/tests/process_vm_writev--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "process_vm_writev.c"
diff --git a/tests/rt_sigqueueinfo--pidns-translation.c b/tests/rt_sigqueueinfo--pidns-translation.c
new file mode 100644
index 00000000..74bfb464
--- /dev/null
+++ b/tests/rt_sigqueueinfo--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "rt_sigqueueinfo.c"
diff --git a/tests/rt_sigqueueinfo.c b/tests/rt_sigqueueinfo.c
index 3d3ae52c..2b037b5f 100644
--- a/tests/rt_sigqueueinfo.c
+++ b/tests/rt_sigqueueinfo.c
@@ -7,6 +7,7 @@
  */
 
 #include "tests.h"
+#include "pidns.h"
 #include <assert.h>
 #include <stdio.h>
 #include <signal.h>
@@ -15,6 +16,10 @@
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	struct sigaction sa = {
 		.sa_handler = SIG_IGN
 	};
@@ -22,15 +27,19 @@ main(void)
 		.sival_ptr = (void *) (unsigned long) 0xdeadbeefbadc0dedULL
 	};
 	pid_t pid = getpid();
+	const char *pid_str = pidns_pid2str(PT_TGID);
 
 	assert(sigaction(SIGUSR1, &sa, NULL) == 0);
 	if (sigqueue(pid, SIGUSR1, value))
 		perror_msg_and_skip("sigqueue");
-	printf("rt_sigqueueinfo(%u, SIGUSR1, {si_signo=SIGUSR1, "
-		"si_code=SI_QUEUE, si_pid=%d, si_uid=%d, "
+	pidns_print_leader();
+	printf("rt_sigqueueinfo(%d%s, SIGUSR1, {si_signo=SIGUSR1, "
+		"si_code=SI_QUEUE, si_pid=%d%s, si_uid=%u, "
 		"si_value={int=%d, ptr=%p}}) = 0\n",
-		pid, pid, getuid(), value.sival_int, value.sival_ptr);
-	printf("+++ exited with 0 +++\n");
+		pid, pid_str, pid, pid_str,
+		getuid(), value.sival_int, value.sival_ptr);
+	pidns_print_leader();
+	puts("+++ exited with 0 +++");
 
 	return 0;
 }
diff --git a/tests/rt_tgsigqueueinfo--pidns-translation.c b/tests/rt_tgsigqueueinfo--pidns-translation.c
new file mode 100644
index 00000000..94396f00
--- /dev/null
+++ b/tests/rt_tgsigqueueinfo--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "rt_tgsigqueueinfo.c"
diff --git a/tests/rt_tgsigqueueinfo.c b/tests/rt_tgsigqueueinfo.c
index 918e41d0..d611f0fd 100644
--- a/tests/rt_tgsigqueueinfo.c
+++ b/tests/rt_tgsigqueueinfo.c
@@ -10,8 +10,9 @@
 
 #include "tests.h"
 #include "scno.h"
+#include "pidns.h"
 
-#ifdef __NR_rt_tgsigqueueinfo
+#if defined __NR_rt_tgsigqueueinfo && defined __NR_gettid
 
 # include <errno.h>
 # include <signal.h>
@@ -20,11 +21,11 @@
 # include <unistd.h>
 
 static long
-k_tgsigqueueinfo(const pid_t pid, const int sig, const void *const info)
+k_tgsigqueueinfo(const pid_t tgid, const int tid, const int sig, const void *const info)
 {
 	return syscall(__NR_rt_tgsigqueueinfo,
-		       F8ILL_KULONG_MASK | pid,
-		       F8ILL_KULONG_MASK | pid,
+		       F8ILL_KULONG_MASK | tgid,
+		       F8ILL_KULONG_MASK | tid,
 		       F8ILL_KULONG_MASK | sig,
 		       info);
 }
@@ -32,6 +33,10 @@ k_tgsigqueueinfo(const pid_t pid, const int sig, const void *const info)
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	const struct sigaction sa = {
 		.sa_handler = SIG_IGN
 	};
@@ -48,17 +53,22 @@ main(void)
 	info->si_value.sival_ptr =
 		(void *) (unsigned long) 0xdeadbeeffacefeedULL;
 
-	if (k_tgsigqueueinfo(info->si_pid, SIGUSR1, info))
+	if (k_tgsigqueueinfo(getpid(), syscall(__NR_gettid), SIGUSR1, info))
 		(errno == ENOSYS ? perror_msg_and_skip : perror_msg_and_fail)(
 			"rt_tgsigqueueinfo");
 
-	printf("rt_tgsigqueueinfo(%u, %u, %s, {si_signo=%s"
-		", si_code=SI_QUEUE, si_errno=ENOENT, si_pid=%d"
+	pidns_print_leader();
+	printf("rt_tgsigqueueinfo(%d%s, %d%s, %s, {si_signo=%s"
+		", si_code=SI_QUEUE, si_errno=ENOENT, si_pid=%d%s"
 		", si_uid=%d, si_value={int=%d, ptr=%p}}) = 0\n",
-		info->si_pid, info->si_pid, "SIGUSR1", "SIGUSR1",
-		info->si_pid, info->si_uid, info->si_value.sival_int,
+		info->si_pid, pidns_pid2str(PT_TGID),
+		info->si_pid, pidns_pid2str(PT_TID),
+		"SIGUSR1", "SIGUSR1",
+		info->si_pid, pidns_pid2str(PT_TGID),
+		info->si_uid, info->si_value.sival_int,
 		info->si_value.sival_ptr);
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/sched_xetaffinity--pidns-translation.c b/tests/sched_xetaffinity--pidns-translation.c
new file mode 100644
index 00000000..814e3989
--- /dev/null
+++ b/tests/sched_xetaffinity--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "sched_xetaffinity.c"
diff --git a/tests/sched_xetaffinity.c b/tests/sched_xetaffinity.c
index cebff3ab..52be85e9 100644
--- a/tests/sched_xetaffinity.c
+++ b/tests/sched_xetaffinity.c
@@ -10,6 +10,7 @@
 
 #include "tests.h"
 #include "scno.h"
+#include "pidns.h"
 #include <sched.h>
 
 #if defined __NR_sched_getaffinity && defined __NR_sched_setaffinity \
@@ -41,8 +42,13 @@ setaffinity(unsigned long pid, unsigned long size, void *set)
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	unsigned int cpuset_size = 1;
 	const pid_t pid = getpid();
+	const char *pid_str = pidns_pid2str(PT_TGID);
 
 	while (cpuset_size) {
 		assert(getaffinity(pid, cpuset_size, NULL) == -1);
@@ -50,18 +56,21 @@ main(void)
 			break;
 		if (EINVAL != errno)
 			perror_msg_and_skip("sched_getaffinity");
-		printf("sched_getaffinity(%d, %u, NULL) = %s\n",
-		       pid, cpuset_size, errstr);
+		pidns_print_leader();
+		printf("sched_getaffinity(%d%s, %u, NULL) = %s\n",
+		       pid, pid_str, cpuset_size, errstr);
 		cpuset_size <<= 1;
 	}
 	assert(cpuset_size);
-	printf("sched_getaffinity(%d, %u, NULL) = %s\n",
-	       pid, cpuset_size, errstr);
+	pidns_print_leader();
+	printf("sched_getaffinity(%d%s, %u, NULL) = %s\n",
+	       pid, pid_str, cpuset_size, errstr);
 
 	cpu_set_t *cpuset = tail_alloc(cpuset_size);
 	getaffinity(pid, cpuset_size, cpuset + 1);
-	printf("sched_getaffinity(%d, %u, %p) = %s\n",
-	       pid, cpuset_size, cpuset + 1, errstr);
+	pidns_print_leader();
+	printf("sched_getaffinity(%d%s, %u, %p) = %s\n",
+	       pid, pid_str, cpuset_size, cpuset + 1, errstr);
 
 	int ret_size = getaffinity(pid, cpuset_size, cpuset);
 	if (ret_size < 0)
@@ -69,7 +78,8 @@ main(void)
 				    pid, (unsigned) cpuset_size, cpuset, errstr);
 	assert(ret_size <= (int) cpuset_size);
 
-	printf("sched_getaffinity(%d, %u, [", pid, cpuset_size);
+	pidns_print_leader();
+	printf("sched_getaffinity(%d%s, %u, [", pid, pid_str, cpuset_size);
 	const char *sep;
 	unsigned int i, cpu;
 	for (i = 0, cpu = 0, sep = ""; i < (unsigned) ret_size * 8; ++i) {
@@ -85,8 +95,9 @@ main(void)
 	CPU_SET_S(cpu, cpuset_size, cpuset);
 	if (setaffinity(pid, cpuset_size, cpuset))
 		perror_msg_and_skip("sched_setaffinity");
-	printf("sched_setaffinity(%d, %u, [%u]) = 0\n",
-	       pid, cpuset_size, cpu);
+	pidns_print_leader();
+	printf("sched_setaffinity(%d%s, %u, [%u]) = 0\n",
+	       pid, pid_str, cpuset_size, cpu);
 
 	const unsigned int big_size = cpuset_size < 128 ? 128 : cpuset_size * 2;
 	cpuset = tail_alloc(big_size);
@@ -95,7 +106,8 @@ main(void)
 		perror_msg_and_fail("sched_getaffinity(%d, %u, %p) = %s\n",
 				    pid, big_size, cpuset, errstr);
 	assert(ret_size <= (int) big_size);
-	printf("sched_getaffinity(%d, %u, [", pid, big_size);
+	pidns_print_leader();
+	printf("sched_getaffinity(%d%s, %u, [", pid, pid_str, big_size);
 	for (i = 0, sep = ""; i < (unsigned) ret_size * 8; ++i) {
 		if (CPU_ISSET_S(i, (unsigned) ret_size, cpuset)) {
 			printf("%s%u", sep, i);
@@ -104,6 +116,7 @@ main(void)
 	}
 	printf("]) = %s\n", errstr);
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/sched_xetattr--pidns-translation.c b/tests/sched_xetattr--pidns-translation.c
new file mode 100644
index 00000000..c152023d
--- /dev/null
+++ b/tests/sched_xetattr--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "sched_xetattr.c"
diff --git a/tests/sched_xetattr.c b/tests/sched_xetattr.c
index c63d7a80..7c5b10e0 100644
--- a/tests/sched_xetattr.c
+++ b/tests/sched_xetattr.c
@@ -15,6 +15,7 @@
 # include <stdio.h>
 # include <sched.h>
 # include <unistd.h>
+# include "pidns.h"
 # include "sched_attr.h"
 # include "xlat.h"
 # include "xlat/schedulers.h"
@@ -41,6 +42,10 @@ sys_sched_setattr(kernel_ulong_t pid, kernel_ulong_t attr, kernel_ulong_t flags)
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	static const kernel_ulong_t bogus_pid =
 		(kernel_ulong_t) 0xdefacedfacefeedULL;
 	static const kernel_ulong_t bogus_size =
@@ -48,20 +53,28 @@ main(void)
 	static const kernel_ulong_t bogus_flags =
 		(kernel_ulong_t) 0xdefaceddeadc0deULL;
 
+	const int pid = getpid();
+	const char *pid_str = pidns_pid2str(PT_TGID);
+
 	TAIL_ALLOC_OBJECT_CONST_PTR(struct sched_attr, attr);
 	TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, psize);
 	void *const efault = attr + 1;
 
-	sys_sched_getattr(0, 0, 0, 0);
-	printf("sched_getattr(0, NULL, 0, 0) = %s\n", errstr);
+	sys_sched_getattr(pid, 0, 0, 0);
+	pidns_print_leader();
+	printf("sched_getattr(%d%s, NULL, 0, 0) = %s\n",
+		pid, pid_str, errstr);
 
 	sys_sched_getattr(0, (unsigned long) attr, 0, 0);
+	pidns_print_leader();
 	printf("sched_getattr(0, %p, 0, 0) = %s\n", attr, errstr);
 
 	sys_sched_getattr(bogus_pid, 0, 0, 0);
+	pidns_print_leader();
 	printf("sched_getattr(%d, NULL, 0, 0) = %s\n", (int) bogus_pid, errstr);
 
 	sys_sched_getattr(-1U, (unsigned long) attr, bogus_size, bogus_flags);
+	pidns_print_leader();
 	printf("sched_getattr(-1, %p, %s%u, %u) = %s\n",
 	       attr,
 # if defined __arm64__ || defined __aarch64__
@@ -72,11 +85,13 @@ main(void)
 	       (unsigned) bogus_size, (unsigned) bogus_flags, errstr);
 
 	sys_sched_getattr(0, (unsigned long) efault, SCHED_ATTR_MIN_SIZE, 0);
+	pidns_print_leader();
 	printf("sched_getattr(0, %p, %u, 0) = %s\n",
 	       efault, (unsigned) SCHED_ATTR_MIN_SIZE, errstr);
 
 	if (sys_sched_getattr(0, (unsigned long) attr, SCHED_ATTR_MIN_SIZE, 0))
 		perror_msg_and_skip("sched_getattr");
+	pidns_print_leader();
 	printf("sched_getattr(0, {size=%u, sched_policy=", attr->size);
 	printxval(schedulers, attr->sched_policy, NULL);
 	printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
@@ -91,11 +106,13 @@ main(void)
 	       (unsigned) SCHED_ATTR_MIN_SIZE);
 
 	sys_sched_getattr(0, (unsigned long) efault, sizeof(*attr), 0);
+	pidns_print_leader();
 	printf("sched_getattr(0, %p, %u, 0) = %s\n",
 	       efault, (unsigned) sizeof(*attr), errstr);
 
 	if (sys_sched_getattr(0, (unsigned long) attr, sizeof(*attr), 0))
 		perror_msg_and_skip("sched_getattr");
+	pidns_print_leader();
 	printf("sched_getattr(0, {size=%u, sched_policy=", attr->size);
 	printxval(schedulers, attr->sched_policy, NULL);
 	printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
@@ -121,11 +138,13 @@ main(void)
 			  F8ILL_KULONG_MASK | sizeof(*attr), F8ILL_KULONG_MASK);
 # if defined __arm64__ || defined __aarch64__
 	if (rc) {
+		pidns_print_leader();
 		printf("sched_getattr(0, %p, 0xffffffff<<32|%u, 0) = %s\n",
 		       attr, (unsigned) sizeof(*attr), errstr);
 	} else
 # endif
 	{
+		pidns_print_leader();
 		printf("sched_getattr(0, {size=%u, sched_policy=", attr->size);
 		printxval(schedulers, attr->sched_policy, NULL);
 		printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
@@ -146,13 +165,16 @@ main(void)
 	}
 
 	sys_sched_setattr(bogus_pid, 0, 0);
+	pidns_print_leader();
 	printf("sched_setattr(%d, NULL, 0) = %s\n", (int) bogus_pid, errstr);
 
 	attr->sched_flags |= 1;
 
-	if (sys_sched_setattr(0, (unsigned long) attr, 0))
+	if (sys_sched_setattr(pid, (unsigned long) attr, 0))
 		perror_msg_and_skip("sched_setattr");
-	printf("sched_setattr(0, {size=%u, sched_policy=", attr->size);
+	pidns_print_leader();
+	printf("sched_setattr(%d%s, {size=%u, sched_policy=",
+		pid, pid_str, attr->size);
 	printxval(schedulers, attr->sched_policy, NULL);
 	printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
 	       ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
@@ -172,6 +194,7 @@ main(void)
 
 	sys_sched_setattr(F8ILL_KULONG_MASK, (unsigned long) attr,
 			  F8ILL_KULONG_MASK);
+	pidns_print_leader();
 	printf("sched_setattr(0, {size=%u, sched_policy=", attr->size);
 	printxval(schedulers, attr->sched_policy, NULL);
 	printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
@@ -193,11 +216,13 @@ main(void)
 	*psize = attr->size;
 
 	sys_sched_setattr(0, (unsigned long) psize, 0);
+	pidns_print_leader();
 	printf("sched_setattr(0, %p, 0) = %s\n", psize, errstr);
 
 	attr->size = 0;
 
 	sys_sched_setattr(0, (unsigned long) attr, 0);
+	pidns_print_leader();
 	printf("sched_setattr(0, {size=%u, sched_policy=", attr->size);
 	printxval(schedulers, attr->sched_policy, NULL);
 	printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
@@ -213,12 +238,14 @@ main(void)
 	attr->size = 1;
 
 	sys_sched_setattr(0, (unsigned long) attr, 0);
+	pidns_print_leader();
 	printf("sched_setattr(0, {size=%u} => {size=%u}, 0) = %s\n",
 	       1, attr->size, errstr);
 
 	attr->size = SCHED_ATTR_MIN_SIZE - 1;
 
 	sys_sched_setattr(0, (unsigned long) attr, 0);
+	pidns_print_leader();
 	printf("sched_setattr(0, {size=%u} => {size=%u}, 0) = %s\n",
 	       SCHED_ATTR_MIN_SIZE - 1, attr->size, errstr);
 
@@ -232,6 +259,7 @@ main(void)
 	attr->sched_period = 0xded1ca7edda7aca7ULL;
 
 	sys_sched_setattr(bogus_pid, (unsigned long) attr, bogus_flags);
+	pidns_print_leader();
 	printf("sched_setattr(%d, {size=%u, sched_policy=%#x /* SCHED_??? */, "
 	       "sched_flags=%#" PRIx64 " /* SCHED_FLAG_??? */, "
 	       "sched_nice=%d, sched_priority=%u, sched_runtime=%" PRIu64 ", "
@@ -274,6 +302,7 @@ main(void)
 	attr->sched_period = 0xded1ca7edda7aca7ULL;
 
 	sys_sched_setattr(bogus_pid, (unsigned long) attr, bogus_flags);
+	pidns_print_leader();
 	printf("sched_setattr(%d, {size=%u, sched_policy=%#x /* SCHED_??? */, "
 	       "sched_flags=SCHED_FLAG_RESET_ON_FORK|SCHED_FLAG_RECLAIM|"
 	       "SCHED_FLAG_DL_OVERRUN|0x80, "
@@ -296,11 +325,13 @@ main(void)
 		const kernel_ulong_t ill = f8ill_ptr_to_kulong(attr);
 
 		sys_sched_getattr(0, ill, sizeof(*attr), 0);
+		pidns_print_leader();
 		printf("sched_getattr(0, %#llx, %u, 0) = %s\n",
 		       (unsigned long long) ill, (unsigned) sizeof(*attr),
 		       errstr);
 
 		sys_sched_setattr(0, ill, 0);
+		pidns_print_leader();
 		printf("sched_setattr(0, %#llx, 0) = %s\n",
 		       (unsigned long long) ill, errstr);
 	}
@@ -310,6 +341,7 @@ main(void)
 	attr->sched_flags = 0x8fULL;
 
 	sys_sched_setattr(bogus_pid, (unsigned long) attr, bogus_flags);
+	pidns_print_leader();
 	printf("sched_setattr(%d, {size=%u, "
 	       "sched_flags=SCHED_FLAG_RESET_ON_FORK|SCHED_FLAG_RECLAIM|"
 	       "SCHED_FLAG_DL_OVERRUN|SCHED_FLAG_KEEP_POLICY|0x80, "
@@ -329,11 +361,13 @@ main(void)
 		const kernel_ulong_t ill = f8ill_ptr_to_kulong(attr);
 
 		sys_sched_getattr(0, ill, sizeof(*attr), 0);
+		pidns_print_leader();
 		printf("sched_getattr(0, %#llx, %u, 0) = %s\n",
 		       (unsigned long long) ill, (unsigned) sizeof(*attr),
 		       errstr);
 
 		sys_sched_setattr(0, ill, 0);
+		pidns_print_leader();
 		printf("sched_setattr(0, %#llx, 0) = %s\n",
 		       (unsigned long long) ill, errstr);
 	}
@@ -342,6 +376,7 @@ main(void)
 	attr->sched_flags = 0xe7ULL;
 
 	sys_sched_setattr(bogus_pid, (unsigned long) attr, bogus_flags);
+	pidns_print_leader();
 	printf("sched_setattr(%d, {size=%u, sched_policy=%#x /* SCHED_??? */, "
 	       "sched_flags=SCHED_FLAG_RESET_ON_FORK|SCHED_FLAG_RECLAIM|"
 	       "SCHED_FLAG_DL_OVERRUN|SCHED_FLAG_UTIL_CLAMP_MIN"
@@ -365,11 +400,13 @@ main(void)
 		const kernel_ulong_t ill = f8ill_ptr_to_kulong(attr);
 
 		sys_sched_getattr(0, ill, sizeof(*attr), 0);
+		pidns_print_leader();
 		printf("sched_getattr(0, %#llx, %u, 0) = %s\n",
 		       (unsigned long long) ill, (unsigned) sizeof(*attr),
 		       errstr);
 
 		sys_sched_setattr(0, ill, 0);
+		pidns_print_leader();
 		printf("sched_setattr(0, %#llx, 0) = %s\n",
 		       (unsigned long long) ill, errstr);
 	}
@@ -377,6 +414,7 @@ main(void)
 	attr->sched_flags = 0xcaffee90LL;
 
 	sys_sched_setattr(bogus_pid, (unsigned long) attr, bogus_flags);
+	pidns_print_leader();
 	printf("sched_setattr(%d, {size=%u, sched_flags=SCHED_FLAG_KEEP_PARAMS"
 	       "|0xcaffee80, sched_util_min=%u, sched_util_max=%u}, %u) = %s\n",
 	       (int) bogus_pid,
@@ -389,15 +427,18 @@ main(void)
 		const kernel_ulong_t ill = f8ill_ptr_to_kulong(attr);
 
 		sys_sched_getattr(0, ill, sizeof(*attr), 0);
+		pidns_print_leader();
 		printf("sched_getattr(0, %#llx, %u, 0) = %s\n",
 		       (unsigned long long) ill, (unsigned) sizeof(*attr),
 		       errstr);
 
 		sys_sched_setattr(0, ill, 0);
+		pidns_print_leader();
 		printf("sched_setattr(0, %#llx, 0) = %s\n",
 		       (unsigned long long) ill, errstr);
 	}
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/sched_xetparam--pidns-translation.c b/tests/sched_xetparam--pidns-translation.c
new file mode 100644
index 00000000..9fb3e579
--- /dev/null
+++ b/tests/sched_xetparam--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "sched_xetparam.c"
diff --git a/tests/sched_xetparam.c b/tests/sched_xetparam.c
index de3915b2..f05ca02d 100644
--- a/tests/sched_xetparam.c
+++ b/tests/sched_xetparam.c
@@ -7,6 +7,7 @@
 
 #include "tests.h"
 #include "scno.h"
+# include "pidns.h"
 
 #if defined __NR_sched_getparam && defined __NR_sched_setparam
 
@@ -17,18 +18,29 @@
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	struct sched_param *const param =
 		tail_alloc(sizeof(struct sched_param));
 
-	long rc = syscall(__NR_sched_getparam, 0, param);
-	printf("sched_getparam(0, [%d]) = %ld\n",
-	       param->sched_priority, rc);
+	const int pid = getpid();
+	const char *pid_str = pidns_pid2str(PT_TGID);
+
+	long rc = syscall(__NR_sched_getparam, pid, param);
+	pidns_print_leader();
+	printf("sched_getparam(%d%s, [%d]) = %ld\n",
+	       pid, pid_str, param->sched_priority, rc);
 
 	param->sched_priority = -1;
-	rc = syscall(__NR_sched_setparam, 0, param);
-	printf("sched_setparam(0, [%d]) = %ld %s (%m)\n",
+	rc = syscall(__NR_sched_setparam, pid, param);
+	pidns_print_leader();
+	printf("sched_setparam(%d%s, [%d]) = %ld %s (%m)\n",
+	       pid, pid_str,
 	       param->sched_priority, rc, errno2name());
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/sched_xetscheduler--pidns-translation.c b/tests/sched_xetscheduler--pidns-translation.c
new file mode 100644
index 00000000..78b794b2
--- /dev/null
+++ b/tests/sched_xetscheduler--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "sched_xetscheduler.c"
diff --git a/tests/sched_xetscheduler.c b/tests/sched_xetscheduler.c
index 047e8676..a0a923fc 100644
--- a/tests/sched_xetscheduler.c
+++ b/tests/sched_xetscheduler.c
@@ -7,6 +7,7 @@
 
 #include "tests.h"
 #include "scno.h"
+#include "pidns.h"
 
 #if defined __NR_sched_getscheduler && defined __NR_sched_setscheduler
 
@@ -17,8 +18,15 @@
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	TAIL_ALLOC_OBJECT_CONST_PTR(struct sched_param, param);
-	long rc = syscall(__NR_sched_getscheduler, 0);
+	const int pid = getpid();
+	const char *pid_str = pidns_pid2str(PT_TGID);
+
+	long rc = syscall(__NR_sched_getscheduler, pid);
 	const char *scheduler;
 	switch (rc) {
 		case SCHED_FIFO:
@@ -50,33 +58,43 @@ main(void)
 		default:
 			scheduler = "SCHED_OTHER";
 	}
-	printf("sched_getscheduler(0) = %ld (%s)\n",
-	       rc, scheduler);
+	pidns_print_leader();
+	printf("sched_getscheduler(%d%s) = %ld (%s)\n",
+	       pid, pid_str, rc, scheduler);
 
 	rc = syscall(__NR_sched_getscheduler, -1);
+	pidns_print_leader();
 	printf("sched_getscheduler(-1) = %s\n", sprintrc(rc));
 
 	param->sched_priority = -1;
 
-	rc = syscall(__NR_sched_setscheduler, 0, SCHED_FIFO, NULL);
-	printf("sched_setscheduler(0, SCHED_FIFO, NULL) = %s\n", sprintrc(rc));
+	rc = syscall(__NR_sched_setscheduler, pid, SCHED_FIFO, NULL);
+	pidns_print_leader();
+	printf("sched_setscheduler(%d%s, SCHED_FIFO, NULL) = %s\n",
+	       pid, pid_str, sprintrc(rc));
 
-	rc = syscall(__NR_sched_setscheduler, 0, SCHED_FIFO, param + 1);
-	printf("sched_setscheduler(0, SCHED_FIFO, %p) = %s\n", param + 1,
-	       sprintrc(rc));
+	rc = syscall(__NR_sched_setscheduler, pid, SCHED_FIFO, param + 1);
+	pidns_print_leader();
+	printf("sched_setscheduler(%d%s, SCHED_FIFO, %p) = %s\n",
+	       pid, pid_str, param + 1, sprintrc(rc));
 
-	rc = syscall(__NR_sched_setscheduler, 0, 0xfaceda7a, param);
-	printf("sched_setscheduler(0, %#x /* SCHED_??? */, [%d]) = %s\n",
-	       0xfaceda7a, param->sched_priority, sprintrc(rc));
+	rc = syscall(__NR_sched_setscheduler, pid, 0xfaceda7a, param);
+	pidns_print_leader();
+	printf("sched_setscheduler(%d%s, %#x /* SCHED_??? */, [%d]) = %s\n",
+	       pid, pid_str, 0xfaceda7a,
+	       param->sched_priority, sprintrc(rc));
 
 	rc = syscall(__NR_sched_setscheduler, -1, SCHED_FIFO, param);
+	pidns_print_leader();
 	printf("sched_setscheduler(-1, SCHED_FIFO, [%d]) = %s\n",
 	       param->sched_priority, sprintrc(rc));
 
-	rc = syscall(__NR_sched_setscheduler, 0, SCHED_FIFO, param);
-	printf("sched_setscheduler(0, SCHED_FIFO, [%d]) = %s\n",
-	       param->sched_priority, sprintrc(rc));
+	rc = syscall(__NR_sched_setscheduler, pid, SCHED_FIFO, param);
+	pidns_print_leader();
+	printf("sched_setscheduler(%d%s, SCHED_FIFO, [%d]) = %s\n",
+	       pid, pid_str, param->sched_priority, sprintrc(rc));
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/signal_receive--pidns-translation.c b/tests/signal_receive--pidns-translation.c
new file mode 100644
index 00000000..b4e3b2f8
--- /dev/null
+++ b/tests/signal_receive--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "signal_receive.c"
diff --git a/tests/signal_receive.c b/tests/signal_receive.c
index ad3b4ebd..1688d21e 100644
--- a/tests/signal_receive.c
+++ b/tests/signal_receive.c
@@ -8,6 +8,7 @@
  */
 
 #include "tests.h"
+#include "pidns.h"
 #include <signal.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -26,10 +27,15 @@ handler(int sig, siginfo_t *info, void *ucontext)
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	static const char prefix[] = "KERNEL BUG";
 	int printed = 0;
 
 	const int pid = getpid();
+	const char *pid_str = pidns_pid2str(PT_TGID);
 	const int uid = geteuid();
 
 	for (int sig = 1; sig <= 31; ++sig) {
@@ -73,10 +79,13 @@ main(void)
 		const int e_pid = s_pid;
 		const int e_uid = s_uid;
 #endif
-		printf("kill(%d, %s) = 0\n", pid, signal2name(sig));
-		printf("--- %s {si_signo=%s, si_code=SI_USER, si_pid=%d"
+		pidns_print_leader();
+		printf("kill(%d%s, %s) = 0\n", pid, pid_str, signal2name(sig));
+		pidns_print_leader();
+		printf("--- %s {si_signo=%s, si_code=SI_USER, si_pid=%d%s"
 		       ", si_uid=%d} ---\n",
-		       signal2name(sig), signal2name(e_sig), e_pid, e_uid);
+		       signal2name(sig), signal2name(e_sig),
+		       e_pid, pid_str, e_uid);
 
 		if (s_code || sig != s_sig || pid != s_pid || uid != s_uid) {
 			/*
@@ -91,11 +100,11 @@ main(void)
 			}
 			fprintf(stderr,
 				"%s: expected: si_signo=%d, si_code=%d"
-				", si_pid=%d, si_uid=%d\n"
+				", si_pid=%d%s, si_uid=%d\n"
 				"%s: received: si_signo=%d, si_code=%d"
-				", si_pid=%d, si_uid=%d\n",
-				prefix, sig, SI_USER, pid, uid,
-				prefix, sig, s_code, s_pid, s_uid);
+				", si_pid=%d%s, si_uid=%d\n",
+				prefix, sig, SI_USER, pid, pid_str, uid,
+				prefix, sig, s_code, s_pid, pid_str, s_uid);
 		}
 	}
 
@@ -104,6 +113,7 @@ main(void)
 			"*** PLEASE FIX THE KERNEL ***\n", prefix);
 	}
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/so_peercred--pidns-translation.c b/tests/so_peercred--pidns-translation.c
new file mode 100644
index 00000000..402bbcfe
--- /dev/null
+++ b/tests/so_peercred--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "so_peercred.c"
diff --git a/tests/so_peercred.c b/tests/so_peercred.c
index 151bb175..ae855b71 100644
--- a/tests/so_peercred.c
+++ b/tests/so_peercred.c
@@ -9,6 +9,7 @@
  */
 
 #include "tests.h"
+#include "pidns.h"
 
 #include <stddef.h>
 #include <stdio.h>
@@ -53,6 +54,10 @@ so_str(void)
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	TAIL_ALLOC_OBJECT_CONST_PTR(struct ucred, peercred);
 	TAIL_ALLOC_OBJECT_CONST_PTR(socklen_t, len);
 
@@ -75,6 +80,8 @@ main(void)
 	struct ucred *const gid_truncated =
 		tail_alloc(sizeof_gid_truncated);
 
+	const char *pid_str = pidns_pid2str(PT_TGID);
+
 	int sv[2];
 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv))
                 perror_msg_and_skip("socketpair AF_UNIX SOCK_STREAM");
@@ -82,8 +89,10 @@ main(void)
 	/* classic getsockopt */
 	*len = sizeof(*peercred);
 	get_peercred(sv[0], peercred, len);
+	pidns_print_leader();
 	printf("getsockopt(%d, %s", sv[0], so_str());
 	PRINT_FIELD_D(", {", *peercred, pid);
+	printf("%s", pid_str);
 	PRINT_FIELD_UID(", ", *peercred, uid);
 	PRINT_FIELD_UID(", ", *peercred, gid);
 	printf("}, [%d]) = %s\n", *len, errstr);
@@ -91,14 +100,17 @@ main(void)
 	/* getsockopt with zero optlen */
 	*len = 0;
 	get_peercred(sv[0], peercred, len);
+	pidns_print_leader();
 	printf("getsockopt(%d, %s, %p, [0]) = %s\n",
 	       sv[0], so_str(), peercred, errstr);
 
 	/* getsockopt with optlen larger than necessary - shortened */
 	*len = sizeof(*peercred) + 1;
 	get_peercred(sv[0], peercred, len);
+	pidns_print_leader();
 	printf("getsockopt(%d, %s", sv[0], so_str());
 	PRINT_FIELD_D(", {", *peercred, pid);
+	printf("%s", pid_str);
 	PRINT_FIELD_UID(", ", *peercred, uid);
 	PRINT_FIELD_UID(", ", *peercred, gid);
 	printf("}, [%u->%d]) = %s\n",
@@ -110,6 +122,7 @@ main(void)
 	 */
 	*len = sizeof_pid_truncated;
 	get_peercred(sv[0], pid_truncated, len);
+	pidns_print_leader();
 	printf("getsockopt(%d, %s, {pid=", sv[0], so_str());
 	print_quoted_hex(pid_truncated, *len);
 	printf("}, [%d]) = %s\n", *len, errstr);
@@ -120,8 +133,10 @@ main(void)
 	 */
 	*len = sizeof_pid;
 	get_peercred(sv[0], pid, len);
+	pidns_print_leader();
 	printf("getsockopt(%d, %s", sv[0], so_str());
 	PRINT_FIELD_D(", {", *pid, pid);
+	printf("%s", pid_str);
 	printf("}, [%d]) = %s\n", *len, errstr);
 
 	/*
@@ -136,8 +151,10 @@ main(void)
 	 * to struct ucred.pid field.
 	 */
 	memcpy(uid, uid_truncated, sizeof_uid_truncated);
+	pidns_print_leader();
 	printf("getsockopt(%d, %s", sv[0], so_str());
 	PRINT_FIELD_D(", {", *uid, pid);
+	printf("%s", pid_str);
 	printf(", uid=");
 	print_quoted_hex(&uid->uid, sizeof_uid_truncated -
 				    offsetof(struct ucred, uid));
@@ -149,8 +166,10 @@ main(void)
 	 */
 	*len = sizeof_uid;
 	get_peercred(sv[0], uid, len);
+	pidns_print_leader();
 	printf("getsockopt(%d, %s", sv[0], so_str());
 	PRINT_FIELD_D(", {", *uid, pid);
+	printf("%s", pid_str);
 	PRINT_FIELD_UID(", ", *uid, uid);
 	printf("}, [%d]) = %s\n", *len, errstr);
 
@@ -166,8 +185,10 @@ main(void)
 	 * to struct ucred.pid and struct ucred.uid fields.
 	 */
 	memcpy(peercred, gid_truncated, sizeof_gid_truncated);
+	pidns_print_leader();
 	printf("getsockopt(%d, %s", sv[0], so_str());
 	PRINT_FIELD_D(", {", *peercred, pid);
+	printf("%s", pid_str);
 	PRINT_FIELD_UID(", ", *peercred, uid);
 	printf(", gid=");
 	print_quoted_hex(&peercred->gid, sizeof_gid_truncated -
@@ -177,14 +198,17 @@ main(void)
 	/* getsockopt optval EFAULT */
 	*len = sizeof(*peercred);
 	get_peercred(sv[0], &peercred->uid, len);
+	pidns_print_leader();
 	printf("getsockopt(%d, %s, %p, [%d]) = %s\n",
 	       sv[0], so_str(), &peercred->uid, *len, errstr);
 
 	/* getsockopt optlen EFAULT */
 	get_peercred(sv[0], peercred, len + 1);
+	pidns_print_leader();
 	printf("getsockopt(%d, %s, %p, %p) = %s\n",
 	       sv[0], so_str(), peercred, len + 1, errstr);
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/xet_robust_list--pidns-translation.c b/tests/xet_robust_list--pidns-translation.c
new file mode 100644
index 00000000..e0477267
--- /dev/null
+++ b/tests/xet_robust_list--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "xet_robust_list.c"
diff --git a/tests/xet_robust_list.c b/tests/xet_robust_list.c
index 43239c8b..8eb8ca54 100644
--- a/tests/xet_robust_list.c
+++ b/tests/xet_robust_list.c
@@ -8,6 +8,7 @@
 
 #include "tests.h"
 #include "scno.h"
+#include "pidns.h"
 
 #if defined __NR_get_robust_list && defined __NR_set_robust_list
 
@@ -30,27 +31,38 @@ sprintaddr(void *addr)
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	const pid_t pid = getpid();
+	const char *pid_str = pidns_pid2str(PT_TGID);
 	const long long_pid = (unsigned long) (0xdeadbeef00000000LL | pid);
 	TAIL_ALLOC_OBJECT_CONST_PTR(void *, p_head);
 	TAIL_ALLOC_OBJECT_CONST_PTR(size_t, p_len);
 
 	if (syscall(__NR_get_robust_list, long_pid, p_head, p_len))
 		perror_msg_and_skip("get_robust_list");
-	printf("get_robust_list(%d, [%s], [%lu]) = 0\n",
-	       (int) pid, sprintaddr(*p_head), (unsigned long) *p_len);
+	pidns_print_leader();
+	printf("get_robust_list(%d%s, [%s], [%lu]) = 0\n",
+	       pid, pid_str, sprintaddr(*p_head),
+	       (unsigned long) *p_len);
 
 	void *head = tail_alloc(*p_len);
 	if (syscall(__NR_set_robust_list, head, *p_len))
 		perror_msg_and_skip("set_robust_list");
+	pidns_print_leader();
 	printf("set_robust_list(%p, %lu) = 0\n",
 	       head, (unsigned long) *p_len);
 
 	if (syscall(__NR_get_robust_list, long_pid, p_head, p_len))
 		perror_msg_and_skip("get_robust_list");
-	printf("get_robust_list(%d, [%s], [%lu]) = 0\n",
-	       (int) pid, sprintaddr(*p_head), (unsigned long) *p_len);
+	pidns_print_leader();
+	printf("get_robust_list(%d%s, [%s], [%lu]) = 0\n",
+	       pid, pid_str, sprintaddr(*p_head),
+	       (unsigned long) *p_len);
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/xetpgid--pidns-translation.c b/tests/xetpgid--pidns-translation.c
new file mode 100644
index 00000000..b6469628
--- /dev/null
+++ b/tests/xetpgid--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "xetpgid.c"
diff --git a/tests/xetpgid.c b/tests/xetpgid.c
index 9b070af2..5088d7f0 100644
--- a/tests/xetpgid.c
+++ b/tests/xetpgid.c
@@ -10,6 +10,7 @@
 
 #include "tests.h"
 #include "scno.h"
+#include "pidns.h"
 
 #if defined __NR_getpgid && defined __NR_setpgid
 
@@ -19,13 +20,23 @@
 int
 main(void)
 {
-	const int pid = getpid();
-	long rc = syscall(__NR_getpgid, F8ILL_KULONG_MASK | pid);
-	printf("getpgid(%d) = %ld\n", pid, rc);
-
-	rc = syscall(__NR_setpgid, F8ILL_KULONG_MASK, F8ILL_KULONG_MASK | pid);
-	printf("setpgid(0, %d) = %ld\n", pid, rc);
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
 
+	const int pid = getpid();
+	long pgid = syscall(__NR_getpgid, F8ILL_KULONG_MASK | pid);
+	pidns_print_leader();
+	printf("getpgid(%d%s) = %ld%s\n", pid, pidns_pid2str(PT_TGID),
+		pgid, pidns_pid2str(PT_PGID));
+
+	long rc = syscall(__NR_setpgid, F8ILL_KULONG_MASK,
+		F8ILL_KULONG_MASK | pgid);
+	pidns_print_leader();
+	printf("setpgid(0, %ld%s) = %s\n", pgid, pidns_pid2str(PT_PGID),
+		sprintrc(rc));
+
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/xetpriority--pidns-translation.c b/tests/xetpriority--pidns-translation.c
new file mode 100644
index 00000000..c93669cb
--- /dev/null
+++ b/tests/xetpriority--pidns-translation.c
@@ -0,0 +1,2 @@
+#define PIDNS_TRANSLATION
+#include "xetpriority.c"
diff --git a/tests/xetpriority.c b/tests/xetpriority.c
index 2d61bd10..ee0e3de4 100644
--- a/tests/xetpriority.c
+++ b/tests/xetpriority.c
@@ -7,6 +7,7 @@
 
 #include "tests.h"
 #include "scno.h"
+#include "pidns.h"
 
 #if defined __NR_getpriority && defined __NR_setpriority
 
@@ -17,15 +18,32 @@
 int
 main(void)
 {
+#ifdef PIDNS_TRANSLATION
+	pidns_test_init();
+#endif
+
 	const int pid = getpid();
+	const int pgid = getpgid(0);
+
 	long rc = syscall(__NR_getpriority, PRIO_PROCESS,
 			  F8ILL_KULONG_MASK | pid);
-	printf("getpriority(PRIO_PROCESS, %d) = %ld\n", pid, rc);
+	pidns_print_leader();
+	printf("getpriority(PRIO_PROCESS, %d%s) = %ld\n",
+		pid, pidns_pid2str(PT_TGID), rc);
 
 	rc = syscall(__NR_setpriority, PRIO_PROCESS,
 		     F8ILL_KULONG_MASK | pid, F8ILL_KULONG_MASK);
-	printf("setpriority(PRIO_PROCESS, %d, 0) = %s\n", pid, sprintrc(rc));
+	pidns_print_leader();
+	printf("setpriority(PRIO_PROCESS, %d%s, 0) = %s\n",
+		pid, pidns_pid2str(PT_TGID), sprintrc(rc));
+
+	rc = syscall(__NR_getpriority, PRIO_PGRP,
+			  F8ILL_KULONG_MASK | pgid);
+	pidns_print_leader();
+	printf("getpriority(PRIO_PGRP, %d%s) = %ld\n",
+		pgid, pidns_pid2str(PT_PGID), rc);
 
+	pidns_print_leader();
 	puts("+++ exited with 0 +++");
 	return 0;
 }
-- 
2.27.0



More information about the Strace-devel mailing list