From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1936) id 488933945C14; Tue, 22 Feb 2022 19:33:55 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 488933945C14 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: John Baldwin To: gdb-cvs@sourceware.org Subject: [binutils-gdb] inf-ptrace: Support async targets in inf_ptrace_target::wait. X-Act-Checkin: binutils-gdb X-Git-Author: John Baldwin X-Git-Refname: refs/heads/master X-Git-Oldrev: 85e8c48c73a5c39a6980f9b2bd16ec96062fc4c3 X-Git-Newrev: ca81b5334e074e6c00137dba00154ef1b4489388 Message-Id: <20220222193355.488933945C14@sourceware.org> Date: Tue, 22 Feb 2022 19:33:55 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 22 Feb 2022 19:33:55 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dca81b5334e07= 4e6c00137dba00154ef1b4489388 commit ca81b5334e074e6c00137dba00154ef1b4489388 Author: John Baldwin Date: Tue Feb 22 11:22:14 2022 -0800 inf-ptrace: Support async targets in inf_ptrace_target::wait. =20 - Handle TARGET_WNOHANG by passing WNOHANG to waitpid and returning TARGET_WAITKIND_IGNORE if there are no events to report. =20 - Handle a race in async mode where SIGCHLD might signal the event pipe for an event that has already been reported. If the event was the exit of the last child process, waitpid() will fail with ECHILD rather than returning a pid of 0. For this case, return TARGET_WAITKIND_NO_RESUMED. Diff: --- gdb/inf-ptrace.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c index 0b94aad54d7..ebcc409b989 100644 --- a/gdb/inf-ptrace.c +++ b/gdb/inf-ptrace.c @@ -289,10 +289,14 @@ inf_ptrace_target::resume (ptid_t ptid, int step, enu= m gdb_signal signal) =20 ptid_t inf_ptrace_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, - target_wait_flags options) + target_wait_flags target_options) { pid_t pid; - int status, save_errno; + int options, status, save_errno; + + options =3D 0; + if (target_options & TARGET_WNOHANG) + options |=3D WNOHANG; =20 do { @@ -300,15 +304,32 @@ inf_ptrace_target::wait (ptid_t ptid, struct target_w= aitstatus *ourstatus, =20 do { - pid =3D waitpid (ptid.pid (), &status, 0); + pid =3D waitpid (ptid.pid (), &status, options); save_errno =3D errno; } while (pid =3D=3D -1 && errno =3D=3D EINTR); =20 clear_sigint_trap (); =20 + if (pid =3D=3D 0) + { + gdb_assert (target_options & TARGET_WNOHANG); + ourstatus->set_ignore (); + return minus_one_ptid; + } + if (pid =3D=3D -1) { + /* In async mode the SIGCHLD might have raced and triggered + a check for an event that had already been reported. If + the event was the exit of the only remaining child, + waitpid() will fail with ECHILD. */ + if (ptid =3D=3D minus_one_ptid && save_errno =3D=3D ECHILD) + { + ourstatus->set_no_resumed (); + return minus_one_ptid; + } + fprintf_unfiltered (gdb_stderr, _("Child process unexpectedly missing: %s.\n"), safe_strerror (save_errno));