qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [Bug 1673976] Re: linux-user clone() can't handle glibc pos


From: Éric Hoffman
Subject: [Qemu-devel] [Bug 1673976] Re: linux-user clone() can't handle glibc posix_spawn() (causes locale-gen to assert)
Date: Fri, 02 Mar 2018 20:59:15 -0000

Ok, yes you are right...

I have looked a bit more on the source code, and indeed, I think
understand the issue with the VFORK with QEMU.  Please correct me if I'm
wrong...

- In the syscall trap handler, it has to use the fork() function to emulate the 
vfork() due to restriction of the vfork() function (as QEMU must continue to 
control the flow of instruction past the call to vfork(), and do a lot more 
things in the child thread before ending up performing a execve() or _exit())
- Also, it can not do a wait() for the emulated child, as this child will 
continue to exist even after it calls execve(), so the parent would stall.
- Then, I taught about doing condition signalling, like waiting for a pthread 
condition signal that the child would send once it come to the point of 
performing the _exit() or execve(), but the child would, for example, need to 
know if execve() was successful, or otherwise the child would continue and set 
an error flag and then call _exit().  We do need that error flag before 
continuing the execution on the parent.  So we can not signal back to the 
parent that the 'emulated vfork' is OK before calling execve(), but we can not 
wait after execve() because if the call is successful, there is no return from 
that function, and code goes outside the control of QEMU.

So, I taught of an idea...  What if, in the TARGET_NR_clone syscall trap, when 
we are called upon a CLONE_VFORK, we do:
- Do a regular fork, as it's currently done, with CLONE_VM flag (so the child 
share the same memory as the parent).  However, we also set a state flag that 
we are in this 'vfork emulation' mode just before the fork (more on that 
bellow...).
- Let the parent wait for the child to terminate (again, more on that 
bellow...).
- Let the child return normally and continue execution, as if the parent was 
waiting.

Then, eventually the child will eventually either end up in the 
TARGET_NR_execve or __NR_exit_group syscall trap.  At which point:
- The child check if it is in 'vfork emulation' mode.  If not, then there's 
nothing special, just continue the way the code is currently written.  If the 
flag is set, then follow on with the steps bellow...
- The child set a flag that tell where it is (TARGET_NR_execve or 
__NR_exit_group, and the arguments passed to that syscall), and that everything 
is ok (it has not simply died meanwhile).
- The child terminate, which resume the parent's execution.

The parent then:
- Clear the 'vfork emulation' flag.
- Look at where the child left (was it performing TARGET_NR_execve or 
__NR_exit_group syscall?  What was the arguments passed to the syscall?).  This 
is pretty easy since the child was writing to the parent's memory space the 
whole time (CLONE_VM).  The parent could even use a flag allocated on it's 
stack before the fork(), since the child will have run with it's own stack 
during that time (so the parent stack is still intact).
- Now that we know what the child wanted to do (what syscall and which 
parameters), the parent (which at his point has no more 'leftover' child), can 
then do a *real* vfork, or otherwise return the proper error code.

It's a bit far fetched, and I'm far from implying that I know much about
QEMU, but this is an idea :-)  Sound like it's pretty straightforward
though.  Basically we just wait for the code between the _clone()
function and the _execve/_exit function to complete, at which point we
take action and we are in measure to assess the status code (and do the
real vfork).

Regards,
Eric

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1673976

Title:
  linux-user clone() can't handle glibc posix_spawn() (causes locale-gen
  to assert)

Status in QEMU:
  New

Bug description:
  I'm running a command (locale-gen) inside of an armv7h chroot mounted
  on my x86_64 desktop by putting qemu-arm-static into /usr/bin/ of the
  chroot file system and I get a core dump.

  locale-gen
  Generating locales...
    en_US.UTF-8...localedef: ../sysdeps/unix/sysv/linux/spawni.c:360: 
__spawnix: Assertion `ec >= 0' failed.
  qemu: uncaught target signal 6 (Aborted) - core dumped
  /usr/bin/locale-gen: line 41:    34 Aborted                 (core dumped) 
localedef -i $input -c -f $charset -A /usr/share/locale/locale.alias $locale

  I've done this same thing successfully for years, but this breakage
  has appeared some time in the last 3 or so months. Possibly with the
  update to qemu version 2.8.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1673976/+subscriptions



reply via email to

[Prev in Thread] Current Thread [Next in Thread]