Help!!!! ptrace (2) problem.

jw at rtgvax.UUCP jw at rtgvax.UUCP
Sun Sep 7 08:04:42 AEST 1986



Hello there.

Another chance for you UNIX gurus to ride in on your white horse's.

This cute little routine is supposed to sit at the heart of our
visual debugger.  Only one problem.  It don't work.  Know one here
can figure out why.  Consensus is "probably a kernal bug".  Have you any idea?
Rtgvax is being shut-down on wednesday so I would appreciate speedy response
if possible.

We are running Ultrix 1.1 on a VAX 11/785.

Compile this baby and type
% a.out <some executable>

on a vax.  It is supposed to leave numbers flying all over the (vt100) screen.
Tell me if it works on your machine.  And how to get it to work on this machine.
The only thing that changes on my screen is the user stack pointer.

Lordy, how I wish we had source!

Disclaimer:  This routine is a quick after hours hack by a couple of summer
interns.  It doesn't represent a plea from the company.  And the company
has no idea that we bothered to try to do this, unless of course they
read it off this posting.

leadsv!  \
ihnp4!   -- rtgvax!jw
hoptoad! /	

---------------------------- cut here ---------------------------------
/*
 * broken.c
 * 
 * supposed to display the registers acting in an executable image.
 *
 * added bonus: dumps out info from symbol table of the executable.
 *	-- too lazy to take it out.
 */

#include <errno.h>
extern int errno;
#include <stdio.h>
#include <a.out.h>
#include <stab.h>
#include <sys/wait.h>
#include <machine/pcb.h>
#define PTRACE_PEEKUSER 3
#define PTRACE_SINGLESTEP 9
#define PTRACE_CONTINUE  (char *)1

main(argc, argv)
int argc;
char **argv;
{
	int fd;
	struct exec execb;
	struct nlist nlistb;
	int i;
	
	if (argc != 2) {
		puts("usage: stab file");
		exit(1);
	}

	fd = open(argv[1], 0);
	if (fd == -1) {
		puts("cannot open a.out file");
		exit(1);
	}

	read(fd, &execb, sizeof( struct exec ) );
	printf("execb.a_syms = %d\n", execb.a_syms);
	printf("N_SYMOFF = %d\n", N_SYMOFF( execb ) );
	printf("N_STROFF = %d\n", N_STROFF( execb ) );

	i = execb.a_syms / sizeof( struct nlist );
	printf("%d nlist structures in symbol table\n", i);

	lseek(fd, N_SYMOFF(execb), 0);

	while( i-- ) {
		read(fd, &nlistb, sizeof( struct nlist ) );

		if ( !(nlistb.n_type & N_STAB) )
			continue;

		switch( nlistb.n_type ) {
		case N_FNAME:	printf(" FNAME"); break;
		case N_FUN:	printf(" FUN  "); break;
		case N_RSYM:	printf(" RSYM "); break;
		case N_SLINE:	printf(" SLINE"); break;
		case N_SO:	printf(" SO   "); break;
		case N_LSYM:	printf(" LSYM "); break;
		case N_PSYM:	printf(" PSYM "); break;
		case N_LBRAC:	printf(" LBRAC"); break;
		case N_RBRAC:	printf(" RBRAC"); break;
		default:	printf(" ???  "); break;
		}

		if (nlistb.n_un.n_strx) {
			char strbuf[300];
			int seekval = lseek(fd, 0, 1);
			lseek(fd, N_STROFF(execb) + nlistb.n_un.n_strx, 0);
			read(fd, strbuf, 100);
			printf(" [%.40s]", strbuf);
			lseek(fd, seekval, 0);
		}
		else {
			printf(" %d", nlistb.n_desc);
			printf(" %d", nlistb.n_value);
		}

		putchar('\n');
	}

	trace(argv[1]);
}


#include <signal.h>
static char *regs[] = { "ksp:", "esp:", "ssp:", "usp:",
		"r0:", "r1:", "r2:", "r3:", "r4:", "r5:", "r6:", "r7:",
		"r8:", "r9:", "r10:", "r11:",
		"ap:", "fp:", "pc:", "psl:", "\0"
};


trace(s)
char *s;
{
	int pid, status, regval, i;
	struct wait wait_buf;
	struct pcb its_pcb;
	register char *addr, regnum;

	pid = fork();
	if ( !pid ) {
		ptrace(0,0,0,0);
		execl(s, s, 0);
		puts("could not execl");
		exit(-1);
	}

	printf("\e[1J");  /*clear screen*/
	for(;;) {
		errno = 0;
		if ( wait(&wait_buf) == -1 )
			perror("wait"), exit();
		if (!(wait_buf.w_stopval == WSTOPPED)) {
			puts("exited"), exit();
		}
		printf ("\[1H"); /* Home cursor */
		for (addr=0, regnum=0; *regs[regnum]; regnum++, addr+=4)
		{
			errno = 0;
			regval = ptrace(PTRACE_PEEKUSER, pid, addr, 0);
			printf("%s: %d\n",regs[regnum], regval);
			if (regval== -1 && errno)
				perror ("ptrace"), exit();
			if ( wait (&status) == -1 )
				perror ("wait"), exit();
		}
		errno = 0;
		if ( ptrace(PTRACE_SINGLESTEP, pid, PTRACE_CONTINUE, 0 ) == -1 )
			perror("ptrace"), exit();
	}
}



More information about the Comp.unix.wizards mailing list