Date: Fri, 27 Apr 2012 15:33:49 -0700 From: Marcel Moolenaar <marcel@xcllnt.net> To: Dmitry Mikulin <dmitrym@juniper.net> Cc: toolchain@freebsd.org Subject: [GDB follow-fork] behavior change for wait() Message-ID: <7B7A25D1-E99D-486A-B1CA-A5CFEA837B81@xcllnt.net>
next in thread | raw e-mail | index | archive | help
--Apple-Mail=_043ECEEC-E8F4-47C1-8A83-5577BA74EA34 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii Hi Dmitry, I've been testing the follow-fork changes in GDB and ran into some weird behavior. Without gdb, my test program (attached) prints something like: fbsdvm% ./fe=20 fe(41042): initial process. Doing fork & exec... fe(41043): child after fork. Doing exec... fe(41043): child after exec. Exiting... fe(41042): child 41043 exited with status 0 In particular: the parent (pid=3D41042) calls wait(2) to reap the child = and the child exits with 0. Under gdb, I see this: fbsdvm% gdb ./fe GNU gdb 6.1.1 [FreeBSD] Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you = are welcome to change it and/or distribute copies of it under certain = conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for = details. This GDB was configured as "i386-marcel-freebsd"... (gdb) br main Breakpoint 1 at 0x80487b0: file fe.c, line 14. (gdb) run Starting program: /usr/home/marcel/fe=20 Breakpoint 1, main (argc=3DError accessing memory address 0x1: Bad = address. ) at fe.c:14 14 { (gdb) n main (argc=3D1, argv=3D0xbfbfebb4) at fe.c:19 19 if (getenv("__FE_FORKED__") !=3D NULL) { (gdb) c Continuing. fe(41141): initial process. Doing fork & exec... [New process 41143] fe(41143): child after fork. Doing exec... fe(41143): child after exec. Exiting... fe(41141): wait(2) failed with error 10 (No child processes) Program exited normally. (gdb)=20 When stepping at least once, the inferior will not be able to properly = wait(2) for its child as it seems to have been reaped already. I suspect this is = done by the debugger -- unintentionally at least. Have you seen this before? --=20 Marcel Moolenaar marcel@xcllnt.net --Apple-Mail=_043ECEEC-E8F4-47C1-8A83-5577BA74EA34 Content-Disposition: attachment; filename=fe.c Content-Type: application/octet-stream; name="fe.c" Content-Transfer-Encoding: 7bit #include <sys/types.h> #include <sys/wait.h> #include <err.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> char *newenv[] = { "__FE_FORKED__=yes", NULL }; int main(int argc, char *argv[]) { int status; pid_t pid; /* Check if we exec'd ourselves after a fork. */ if (getenv("__FE_FORKED__") != NULL) { printf("%s(%d): child after exec. Exiting...\n", getprogname(), getpid()); return (0); } printf("%s(%d): initial process. Doing fork & exec...\n", getprogname(), getpid()); pid = fork(); switch (pid) { default: /* parent */ status = -1; pid = wait(&status); if (pid == -1) printf("%s(%d): wait(2) failed with error %d (%s)\n", getprogname(), getpid(), errno, strerror(errno)); else printf("%s(%d): child %d exited with status %d\n", getprogname(), getpid(), pid, status); break; case 0: /* child */ printf("%s(%d): child after fork. Doing exec...\n", getprogname(), getpid()); setenv("__FE_FORKED__", "done", 1); execve(getprogname(), argv, newenv); err(2, "exec failed"); break; case -1: err(1, "fork failed"); } return (0); } --Apple-Mail=_043ECEEC-E8F4-47C1-8A83-5577BA74EA34--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?7B7A25D1-E99D-486A-B1CA-A5CFEA837B81>