lkml.org 
[lkml]   [2008]   [Feb]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRe: [PATCH] x86_64: make traps on 'iret' be debuggable in user space
    Date
    > thanks, applied. I suppose you have a testcase for this that we could try?

    This should exit 0 and show "wait status 0xb7f", and does on i386.
    On 2.6.24 it exits 1 and shows "wait status 0xb".

    Note, on the current tree before [PATCH] x86_64: fix iret exception recovery
    that I also posted today, this will instead produce pathological weirdness
    probably with a quick crash or silent reboot, from running with the wrong GS.

    Thanks,
    Roland

    ---
    #define _GNU_SOURCE
    #include <assert.h>
    #include <errno.h>
    #include <unistd.h>
    #include <signal.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/wait.h>
    #include <stddef.h>
    #include <sys/ptrace.h>
    #include <asm/ptrace.h>
    #include <asm/user.h>

    static pid_t child;

    static void
    cleanup (void)
    {
    if (child != 0)
    kill (child, SIGKILL);
    }

    static void
    handler_fail (int signo)
    {
    cleanup ();

    signal (SIGABRT, SIG_DFL);
    abort ();
    }

    int main (void)
    {
    long l;
    int status, i;
    pid_t pid;
    long cs;

    setbuf (stdout, NULL);
    atexit (cleanup);
    signal (SIGABRT, handler_fail);
    signal (SIGINT, handler_fail);
    signal (SIGALRM, handler_fail);
    alarm (10);

    signal (SIGUSR1, SIG_IGN);
    signal (SIGUSR2, SIG_IGN);

    child = fork ();
    switch (child)
    {
    case -1:
    assert_perror (errno);
    assert (0);
    case 0:
    l = ptrace (PTRACE_TRACEME, 0, NULL, NULL);
    assert (l == 0);
    i = raise (SIGUSR1);
    assert (i == 0);
    assert (0);
    default:
    break;
    }

    pid = waitpid (child, &status, 0);
    assert (pid == child);
    assert (WIFSTOPPED (status));
    assert (WSTOPSIG (status) == SIGUSR1);

    cs = 0xFFFF;

    l = ptrace (PTRACE_POKEUSER, child,
    (void *) offsetof (struct user_regs_struct, cs), (void *) cs);
    assert (l == 0);

    l = ptrace (PTRACE_CONT, child, NULL, NULL);
    assert (l == 0);

    pid = waitpid (child, &status, 0);
    assert (pid == child);

    printf ("wait status %#x\n", status);

    return WIFSTOPPED (status) ? 0 : 1;
    }


    \
     
     \ /
      Last update: 2008-02-05 09:17    [W:0.026 / U:0.508 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site