lkml.org 
[lkml]   [2005]   [Jan]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: 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@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 14:09    [W:4.181 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site