From owner-freebsd-hackers Tue Feb 5 11:14:16 2002 Delivered-To: freebsd-hackers@freebsd.org Received: from bingnet2.cc.binghamton.edu (bingnet2.cc.binghamton.edu [128.226.1.18]) by hub.freebsd.org (Postfix) with ESMTP id 9A6C337B427 for ; Tue, 5 Feb 2002 11:14:06 -0800 (PST) Received: from onyx (onyx.cs.binghamton.edu [128.226.140.171]) by bingnet2.cc.binghamton.edu (8.11.6/8.11.6) with ESMTP id g15JE5E15090 for ; Tue, 5 Feb 2002 14:14:05 -0500 (EST) Date: Tue, 5 Feb 2002 14:12:52 -0500 (EST) From: Zhihui Zhang X-Sender: zzhang@onyx To: freebsd-hackers@freebsd.org Subject: Ptrace and SIGTRAP problem Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG This is a mystery to me. I have gone through some kernel code without luck. The following small program demonstrates that a parent process can write into the data space of its child by ptrace(). If the parent waits for the child to exit, there is no problem. However, if the parent does not do so, the child will get a SIGTRAP signal and core dumps. Can anyone give me a clue how this is the case? Thanks! /* * Filename: trace.c - child process. Use cc -o trace trace.c to compile */ int data[8] = { 0, 0 }; main() { int i; printf("\n"); for (i = 0; i < 8; i++) printf("trace: addr = 0x%x: data[%d] = %d\n", &data[i], i, data[i]); printf("ptrace data addr 0x%x\n", &data[0]); exit(0); } Please run trace first to get the start address of data[8]. This address will be given to the parent process. /* * Filename: debug.c - parent process */ #include #include #include #include #include main(int argc, char * argv[]) { caddr_t addr; int i, pid, ret, data, status; if (argc != 2) { printf("Usage: debug address\n"); exit(0); } sscanf(argv[1], "%x", &addr); if ((pid = fork()) == 0) { ptrace(PT_TRACE_ME, 0, 0, 0); execl("./trace", "trace", 0); /* l - list */ printf("Fail to execl() child process!\n"); exit(1); } printf("Child %d array address is 0x%x\n", pid, addr); ret = waitpid(pid, &status, 0); printf("ret = %d, status = %d\n", ret, status); for (i = 0; i < 8; i++) { /* * Write value of i into address addr in proc pid. */ if (ptrace(PT_WRITE_D, pid, addr, i) == -1) { printf("ptrace error = %d\n", errno); exit(0); } addr += sizeof(int); } if (ptrace(PT_CONTINUE, pid, (caddr_t)1, 0) == -1) { printf("ptrace error = %d\n", errno); exit(0); } #if 1 /* * Without this waitpid(), the child (trace) will core dump. */ ret = waitpid(pid, &status, 0); printf("ret = %d, status = %d\n", ret, status); #endif } /* end of main() */ -Zhihui To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message