Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Feb 2002 14:12:52 -0500 (EST)
From:      Zhihui Zhang <zzhang@cs.binghamton.edu>
To:        freebsd-hackers@freebsd.org
Subject:   Ptrace and SIGTRAP problem
Message-ID:  <Pine.SOL.4.21.0202051400500.14264-100000@onyx>

next in thread | raw e-mail | index | archive | help

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 <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ptrace.h>

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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.SOL.4.21.0202051400500.14264-100000>