Date: Thu, 14 Jun 2018 11:31:20 +0300 From: Yanko Yankulov <yanko.yankulov@gmail.com> To: freebsd-emulation@freebsd.org Subject: two proposed linuxulator fixes + ptrace Message-ID: <CABTd0_pqdAtHMH9gSJdebstASuoomYw1XLbkbbsMCUvtE-=vDA@mail.gmail.com>
index | next in thread | raw e-mail
[-- Attachment #1 --]
Hi all,
I stumbled on two problems trying to run a proprietary java/native Linux
app on FreeBSD. I managed to get it working with two small changes to the
Linux compatibility code. Also in order to pinpoint the issues I got the
ptrace system working for Linux apps, enabling truss & gdb.
This is all on recent CURRENT.
The patches work for me, but I am absolutely sure there is better way to do
this, especially for the ptrace part.
The first issue was 100% CPU usage on start with no progress. Turned out
that the app was expecting TracerPid field in its /proc/pid/status, so just
adding "sbuf_printf(sb, "TracerPid:\t%d\n", 0);" in
linprocfs_doprocstatus solved it.
The second was random segfaults in the Java code. Traced it to mangled r10
in the sigreturn path. Just preserving the r10 when returning from
sigreturn resolves it.
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -228,8 +228,9 @@ linux_set_syscall_retval(struct thread *td, int error)
* the syscall. So, do not clobber %rdx and %r10.
*/
td->td_retval[1] = frame->tf_rdx;
- frame->tf_r10 = frame->tf_rcx;
-
+ if( td->td_sa.code != LINUX_SYS_linux_rt_sigreturn )
+ frame->tf_r10 = frame->tf_rcx;
+
cpu_set_syscall_retval(td, error);
/* Restore all registers. */
So this two fixes solved my issues and was able to run/use the problematic
application.
The ptrace code is lot more messy, and I am really not happy with it, but I
didn't have the time to figure out a cleaner solution. Attaching it
though, as it at least might help someone to devise a better fix.
Best,
Yanko
[-- Attachment #2 --]
From 80957eaff9df2567e2d5bb5b9e73afc397e4d4ae Mon Sep 17 00:00:00 2001
From: Yanko Yankulov <yanko.yankulov@gmail.com>
Date: Thu, 14 Jun 2018 10:44:22 +0300
Subject: [PATCH 1/3] linprocfs: return 0 TracerPid
---
sys/compat/linprocfs/linprocfs.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 586259f28315..31dc4c4ab252 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -805,6 +805,7 @@ linprocfs_doprocstatus(PFS_FILL_ARGS)
sbuf_printf(sb, "Pid:\t%d\n", p->p_pid);
sbuf_printf(sb, "PPid:\t%d\n", p->p_pptr ?
p->p_pptr->p_pid : 0);
+ sbuf_printf(sb, "TracerPid:\t%d\n", 0);
sbuf_printf(sb, "Uid:\t%d %d %d %d\n", p->p_ucred->cr_ruid,
p->p_ucred->cr_uid,
p->p_ucred->cr_svuid,
--
2.17.1
[-- Attachment #3 --]
From ba000110cf1014f589fe52f936e12ad5ac464563 Mon Sep 17 00:00:00 2001
From: Yanko Yankulov <yanko.yankulov@gmail.com>
Date: Thu, 14 Jun 2018 10:49:06 +0300
Subject: [PATCH 2/3] linuxlator: enable ptrace
---
sys/compat/linux/linux_fork.c | 40 +++++++++++++++++++++++++++++++++--
sys/kern/kern_fork.c | 22 ++++++++++---------
2 files changed, 50 insertions(+), 12 deletions(-)
diff --git a/sys/compat/linux/linux_fork.c b/sys/compat/linux/linux_fork.c
index 9dda457e8481..f3d067594502 100644
--- a/sys/compat/linux/linux_fork.c
+++ b/sys/compat/linux/linux_fork.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
+#include <sys/ptrace.h>
#include <sys/racct.h>
#include <sys/sched.h>
#include <sys/syscallsubr.h>
@@ -96,7 +97,17 @@ linux_fork(struct thread *td, struct linux_fork_args *args)
TD_SET_CAN_RUN(td2);
sched_add(td2, SRQ_BORING);
thread_unlock(td2);
-
+
+ PROC_LOCK(p2);
+ /*
+ * Wait until debugger is attached to child.
+ */
+ while (td2->td_proc == p2 && (td2->td_dbgflags & TDB_STOPATFORK) != 0)
+ cv_wait(&p2->p_dbgwait, &p2->p_mtx);
+ _PRELE(p2);
+ racct_proc_fork_done(p2);
+ PROC_UNLOCK(p2);
+
return (0);
}
@@ -132,7 +143,19 @@ linux_vfork(struct thread *td, struct linux_vfork_args *args)
TD_SET_CAN_RUN(td2);
sched_add(td2, SRQ_BORING);
thread_unlock(td2);
+
+ PROC_LOCK(p2);
+ /*
+ * Wait until debugger is attached to child.
+ */
+ while (td2->td_proc == p2 && (td2->td_dbgflags & TDB_STOPATFORK) != 0)
+ cv_wait(&p2->p_dbgwait, &p2->p_mtx);
+ _PRELE(p2);
+ racct_proc_fork_done(p2);
+ PROC_UNLOCK(p2);
+
+
return (0);
}
@@ -251,7 +274,17 @@ linux_clone_proc(struct thread *td, struct linux_clone_args *args)
TD_SET_CAN_RUN(td2);
sched_add(td2, SRQ_BORING);
thread_unlock(td2);
-
+
+ PROC_LOCK(p2);
+ /*
+ * Wait until debugger is attached to child.
+ */
+ while (td2->td_proc == p2 && (td2->td_dbgflags & TDB_STOPATFORK) != 0)
+ cv_wait(&p2->p_dbgwait, &p2->p_mtx);
+ _PRELE(p2);
+ racct_proc_fork_done(p2);
+ PROC_UNLOCK(p2);
+
td->td_retval[0] = p2->p_pid;
return (0);
@@ -350,6 +383,9 @@ linux_clone_thread(struct thread *td, struct linux_clone_args *args)
thread_unlock(td);
if (P_SHOULDSTOP(p))
newtd->td_flags |= TDF_ASTPENDING | TDF_NEEDSUSPCHK;
+
+ if (p->p_ptevents & PTRACE_LWP)
+ newtd->td_dbgflags |= TDB_BORN;
PROC_UNLOCK(p);
tidhash_add(newtd);
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index f8eb84b1b8e9..b1883a5af76b 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -768,19 +768,21 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread *
thread_unlock(td2);
if (fr->fr_pidp != NULL)
*fr->fr_pidp = p2->p_pid;
+
+ PROC_LOCK(p2);
+ /*
+ * Wait until debugger is attached to child.
+ */
+ while (td2->td_proc == p2 && (td2->td_dbgflags & TDB_STOPATFORK) != 0)
+ cv_wait(&p2->p_dbgwait, &p2->p_mtx);
+ _PRELE(p2);
+ racct_proc_fork_done(p2);
+ PROC_UNLOCK(p2);
} else {
*fr->fr_procp = p2;
}
-
- PROC_LOCK(p2);
- /*
- * Wait until debugger is attached to child.
- */
- while (td2->td_proc == p2 && (td2->td_dbgflags & TDB_STOPATFORK) != 0)
- cv_wait(&p2->p_dbgwait, &p2->p_mtx);
- _PRELE(p2);
- racct_proc_fork_done(p2);
- PROC_UNLOCK(p2);
+
+
}
int
--
2.17.1
[-- Attachment #4 --]
From c7f9c5058101f3c53f57c3c1a55d8a88231a2437 Mon Sep 17 00:00:00 2001
From: Yanko Yankulov <yanko.yankulov@gmail.com>
Date: Thu, 14 Jun 2018 11:02:56 +0300
Subject: [PATCH 3/3] linuxlator/amd64; don't mangle r10 on sigreturn
---
sys/amd64/linux/linux_sysvec.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
index cd5c8bd382dc..2077b623876c 100644
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -228,8 +228,9 @@ linux_set_syscall_retval(struct thread *td, int error)
* the syscall. So, do not clobber %rdx and %r10.
*/
td->td_retval[1] = frame->tf_rdx;
- frame->tf_r10 = frame->tf_rcx;
-
+ if( td->td_sa.code != LINUX_SYS_linux_rt_sigreturn )
+ frame->tf_r10 = frame->tf_rcx;
+
cpu_set_syscall_retval(td, error);
/* Restore all registers. */
--
2.17.1
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CABTd0_pqdAtHMH9gSJdebstASuoomYw1XLbkbbsMCUvtE-=vDA>
