Track whether a thread is currently vforked.
Our various fd debugging facilities get extremely confused by a vforked
process closing file descriptors in preparation to exec: fdsan can
abort, and fdtrack will delete backtraces for any file descriptors that
get closed. Keep track of whether we're in a vforked child in order to
be able to detect this.
Bug: http://b/153926671
Test: 32/64-bit bionic-unit-tests on blueline, x86_64 emulator
Change-Id: I8a082fd06bfdfef0e2a88dbce350b6f667f7df9f
diff --git a/libc/arch-arm/bionic/vfork.S b/libc/arch-arm/bionic/vfork.S
index 6855db7..a964be5 100644
--- a/libc/arch-arm/bionic/vfork.S
+++ b/libc/arch-arm/bionic/vfork.S
@@ -31,17 +31,27 @@
ENTRY(vfork)
__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(vfork)
- // __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
+ // r3 = &__get_tls()[TLS_SLOT_THREAD_ID]
mrc p15, 0, r3, c13, c0, 3
ldr r3, [r3, #(TLS_SLOT_THREAD_ID * 4)]
- mov r0, #0
+
+ // Set cached_pid_ to 0, vforked_ to 1, and stash the previous value.
+ mov r0, #0x80000000
+ ldr r1, [r3, #12]
str r0, [r3, #12]
mov ip, r7
ldr r7, =__NR_vfork
swi #0
mov r7, ip
+
+ teq r0, #0
+ bxeq lr
+
+ // rc != 0: reset cached_pid_ and vforked_.
+ str r1, [r3, #12]
cmn r0, #(MAX_ERRNO + 1)
+
bxls lr
neg r0, r0
b __set_errno_internal