From 9f09388caef95b8ce8457c8e19ffd2718e1fc6ce Mon Sep 17 00:00:00 2001
From: "Matthew \"strager\" Glazar" <strager.nds@gmail.com>
Date: Fri, 3 Mar 2023 18:35:35 -0800
Subject: [PATCH] fix mch_job_status giving wrong answer for ptraced processes

I want to debug a child process of Vim using a debugger like lldb. These
debuggers use ptrace. ptrace has the effect of reparenting the process.

This reparenting of Vim's child processes confuses Vim. mch_job_status
calls waitpid to detect whether the child process is alive or not, but
waitpid returns -1 (ECHILD) for these ptrace-reparented processes.

Teach Vim to check if the process is really alive using the kill
syscall with signal 0. If it is alive with another parent, treat the job
as still running.
---
 src/os_unix.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git src/os_unix.c src/os_unix.c
index 0dfbd4977..59698544d 100644
--- src/os_unix.c
+++ src/os_unix.c
@@ -5863,10 +5863,18 @@ mch_job_status(job_T *job)
 # endif
     if (wait_pid == -1)
     {
+	int waitpid_error = errno;
+	if (waitpid_error == ECHILD && mch_process_running(job->jv_pid))
+	{
+		// The process is alive, but it was reparented (for example by
+		// ptrace called by a debugger like lldb or gdb).
+		// HACK(strager): This assumes that process IDs are not reused.
+		return "run";
+	}
 	// process must have exited
 	if (job->jv_status < JOB_ENDED)
 	    ch_log(job->jv_channel, "Job no longer exists: %s",
-							      strerror(errno));
+							      strerror(waitpid_error));
 	goto return_dead;
     }
     if (wait_pid == 0)
-- 
2.33.1

