Google luky.org euqset.org

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ptrace single-stepping change breaks Wine


On Fri, 31 Dec 2004, Linus Torvalds wrote:

> 
> 
> On Fri, 31 Dec 2004, Davide Libenzi wrote:
> > 
> > I don't think Linus ever posted a POPF-only patch. Try to comment those 
> > lines in his POPF patch ...
> 
> Here the two patches are independently, if people want to take a look.
> 
> If somebody wants to split (and test) the TF-careful thing further (the
> "send_sigtrap()" changes are independent, I think), that would be
> wonderful... Hint hint.

I used the test program below on 2.4.27, 2.6.8.1 and latest BK + TF-careful. 
In all cases single stepping over POPF succeeded. In the 2.4.27 and 2.6.8.1
cases, we lost the instruction following "int $0x80" (since 2.6.8.1 
removed the test I put in do_syscall_trace()). The latest BK plus TF-careful 
gets things right WRT single-step-after-syscall case. What was your test 
case about non-working single step over POPF?




- Davide




#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <linux/user.h>
#include <linux/unistd.h>


#define INEXT(i, n) ((i + 1) % n)



int main(int ac, char **av) {
	int i, nins, miss, status, res;
	long start, end;
	long inss[32];
	pid_t cpid, pid;
	struct user_regs_struct ur;
	struct sigaction sa;

	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sa.sa_handler = SIG_DFL;
	sigaction(SIGCHLD, &sa, NULL);

	if (ac > 1) {
		fprintf(stderr, "tracee child: pid=%d\n", getpid());

	loop:
	l0:
		__asm__ volatile ("mov %0, %%eax\n\t":: "I" (__NR_getpid));
	l1:
		__asm__ volatile ("int $0x80\n\t");
	l2:
		__asm__ volatile ("xor %eax, %eax\n\t");
	l3:
		__asm__ volatile ("pushf\n\t");
	l4:
		__asm__ volatile ("pop %eax\n\t");
	l5:
		__asm__ volatile ("orl $0x100, %eax\n\t");
	l6:
		__asm__ volatile ("push %eax\n\t");
	l7:
		__asm__ volatile ("popf\n\t");
	l8:
		__asm__ volatile ("xor %eax, %eax\n\t");
	l9:
		goto loop;
	endloop:
		exit(0);
	}

	if ((cpid = fork()) == 0) {
		fprintf(stderr, "tracee: pid=%d\n", getpid());
		ptrace(PTRACE_TRACEME, 0, NULL, NULL);

		execl(av[0], av[0], "child", NULL);
		exit(1);
	}

	start = (long) &&loop;
	end = (long) &&endloop;
	nins = 0;
	inss[nins++] = (long) &&l0;
	inss[nins++] = (long) &&l1;
	inss[nins++] = (long) &&l2;
	inss[nins++] = (long) &&l3;
	inss[nins++] = (long) &&l4;
	inss[nins++] = (long) &&l5;
	inss[nins++] = (long) &&l6;
	inss[nins++] = (long) &&l7;
	inss[nins++] = (long) &&l8;
	inss[nins++] = (long) &&l9;

	fprintf(stderr, "tracer: child=%d\n", cpid);

	for (;;) {
		pid = wait(&status);
		if (pid != cpid)
			continue;
		res = WSTOPSIG(status);
		if (ptrace(PTRACE_GETREGS, pid, NULL, &ur)) {
			perror("ptrace(PTRACE_GETREGS)");
			return 1;
		}

		if (ptrace(PTRACE_SINGLESTEP, pid, NULL, res != SIGTRAP ? res: 0)) {
			perror("ptrace(PTRACE_SINGLESTEP)");
			return 1;
		}

		if (ur.eip == start)
			break;
	}
	fprintf(stdout, "EIP=0x%08x (0)\n", ur.eip);
	for (i = 1;;) {
		fprintf(stderr, "waiting ...\n");
		pid = wait(&status);
		fprintf(stderr, "done: pid=%d  status=0x%08x (%d)\n",
			pid, status, status);
		if (pid != cpid)
			continue;
		res = WSTOPSIG(status);
		fprintf(stderr, "sig=%d\n", res);
		if (ptrace(PTRACE_GETREGS, pid, NULL, &ur)) {
			perror("ptrace(PTRACE_GETREGS)");
			return 1;
		}
		for (miss = 0; miss < nins && inss[i] != ur.eip; miss++) {
			fprintf(stderr, "missed ins at 0x%08x (%d)\n", inss[i], i);
			i = INEXT(i, nins);
		}
		if (miss == nins) {
			fprintf(stderr, "EIP=0x%08x - lost contact with apollo-%d\n",
				ur.eip, cpid);
			break;
		}
		fprintf(stdout, "EIP=0x%08x (%d)\n", ur.eip, i);
		i = INEXT(i, nins);
		if (ur.eip == start)
			break;

		if (ptrace(PTRACE_SINGLESTEP, pid, NULL, res != SIGTRAP ? res: 0)) {
			perror("ptrace(PTRACE_SINGLESTEP)");
			return 1;
		}
	}
	if (ptrace(PTRACE_CONT, cpid, NULL, SIGKILL)) {
		perror("ptrace(PTRACE_CONT)");
		return 1;
	}

	return 0;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


$B$3$N>pJs$,$"$J$?$NC5$7$F$$?$b$N$+$I$&$+A*Br$7$F$/$@$5$!#(B
yes/$B$^$5$K$3$l$@!*(B   no/$B0c$&$J$!(B   part/$B0lIt8+$D$+$C$?(B   try/$B$3$l$G;n$7$F$_$k(B

$B$"$J$?$,C5$7$F$$?>pJs$O$I$N$h$&$J$3$H$+!"$4<+M3$K5-F~2<$5$!#FC$K!V$^$5$K$3$l$@!*!W$H8@$&>l9g$O5-F~$r$*4j$$7$^$9!#(B
$BNc(B:$B!VJ#?t$N%^%7%s$+$i(BCATV$B7PM3$G(Bipmasquerade$B$rMxMQ$7$F(BWeb$B$r;2>H$7$?$>l9g$N@_Dj$K$D$$F!W(B
Follow-Ups: References: