예제 #1
0
static void print_backtrace(FILE *outb)
{
    /*
     * In general dbx seems to do a better job than gdb.
     *
     * Different dbx implementations require different flags/commands.
     */
#if defined(Q_OS_AIX)
    if(backtrace_command(outb, "dbx -a %d 2>/dev/null <<EOF\n"
                         "where\n"
                         "detach\n"
                         "EOF\n",
                         (int)getpid()))
        return;
    if(backtrace_command(outb, "gdb -q %s %d 2>/dev/null <<EOF\n"
                         "set prompt\n"
                         "where\n"
                         "detach\n"
                         "quit\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
#elif defined(Q_OS_FREEBSD)
    /*
     * FreeBSD insists on sending a SIGSTOP to the process we
     * attach to, so we let the debugger send a SIGCONT to that
     * process after we have detached.
     */
    if(backtrace_command(outb, "gdb -q %s %d 2>/dev/null <<EOF\n"
                         "set prompt\n"
                         "where\n"
                         "detach\n"
                         "shell kill -CONT %d\n"
                         "quit\n"
                         "EOF\n",
                         globalProgName, (int)getpid(), (int)getpid()))
        return;
#elif defined(Q_OS_HPUX)
    /*
     * HP decided to call their debugger xdb.
     *
     * This does not seem to work properly yet. The debugger says
     * "Note: Stack traces may not be possible until you are
     *  stopped in user code." on HP-UX 09.01
     *
     * -L = line-oriented interface.
     * "T [depth]" gives a stacktrace with local variables.
     * The final "y" is confirmation to the quit command.
     */
    if(backtrace_command(outb, "xdb -P %d -L %s 2>&1 <<EOF\n"
                         "T 50\n"
                         "q\ny\n"
                         "EOF\n",
                         (int)getpid(), globalProgName))
        return;
    if(backtrace_command(outb, "gdb -q %s %d 2>/dev/null <<EOF\n"
                         "set prompt\n"
                         "where\n"
                         "detach\n"
                         "quit\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
#elif defined(Q_OS_IRIX)
    /*
     * "set $page=0" drops hold mode
     * "dump ." displays the contents of the variables
     */
    if(backtrace_command(outb, "dbx -p %d 2>/dev/null <<EOF\n"
                         "set \\$page=0\n"
                         "where\n"
# if !defined(__GNUC__)
                         /* gcc does not generate this information */
                         "dump .\n"
# endif
                         "detach\n"
                         "EOF\n",
                         (int)getpid()))
        return;

# if defined(USE_LIBEXC)
    if(trace_back_stack_and_print())
        return;
# endif
    if(backtrace_command(outb, "gdb -q %s %d 2>/dev/null <<EOF\n"
                         "set prompt\n"
                         "where\n"
                         "echo ---\\n\n"
                         "frame 5\n"      /* Skip signal handler frames */
                         "set \\$x = 50\n"
                         "while (\\$x)\n" /* Print local variables for each frame */
                         "info locals\n"
                         "up\n"
                         "set \\$x--\n"
                         "end\n"
                         "echo ---\\n\n"
                         "detach\n"
                         "quit\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
#elif defined(Q_OS_OSF)
    if(backtrace_command(outb, "dbx -pid %d %s 2>/dev/null <<EOF\n"
                         "where\n"
                         "detach\n"
                         "quit\n"
                         "EOF\n",
                         (int)getpid(), globalProgName))
        return;
    if(backtrace_command(outb, "gdb -q %s %d 2>/dev/null <<EOF\n"
                         "set prompt\n"
                         "where\n"
                         "detach\n"
                         "quit\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
#elif defined(Q_OS_SCO)
    /*
     * SCO OpenServer dbx is like a catch-22. The 'detach' command
     * depends on whether ptrace(S) support detaching or not. If it
     * is supported then 'detach' must be used, otherwise the process
     * will be killed upon dbx exit. If it isn't supported then 'detach'
     * will cause the process to be killed. We do not want it to be
     * killed.
     *
     * Out of two evils, the omission of 'detach' was chosen because
     * it worked on our system.
     */
    if(backtrace_command(outb, "dbx %s %d 2>/dev/null <<EOF\n"
                         "where\n"
                         "quit\nEOF\n",
                         globalProgName, (int)getpid()))
        return;
    if(backtrace_command(outb, "gdb -q %s %d 2>/dev/null <<EOF\n"
                         "set prompt\n"
                         "where\n"
                         "detach\n"
                         "quit\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
#elif defined(Q_OS_SOLARIS)
    if(backtrace_command(outb, "dbx %s %d 2>/dev/null <<EOF\n"
                         "where\n"
                         "detach\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
    if(backtrace_command(outb, "gdb -q %s %d 2>/dev/null <<EOF\n"
                         "set prompt\n"
                         "where\n"
                         "echo ---\\n\n"
                         "frame 5\n"      /* Skip signal handler frames */
                         "set \\$x = 50\n"
                         "while (\\$x)\n" /* Print local variables for each frame */
                         "info locals\n"
                         "up\n"
                         "set \\$x--\n"
                         "end\n"
                         "echo ---\\n\n"
                         "detach\n"
                         "quit\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
    if(backtrace_command(outb, "/usr/proc/bin/pstack %d",
                         (int)getpid()))
        return;
    /*
     * Other Unices (AIX, HPUX, SCO) also have adb, but
     * they seem unable to attach to a running process.)
     */
    if(backtrace_command(outb, "adb %s 2>&1 <<EOF\n"
                         "0t%d:A\n" /* Attach to pid */
                         "\\$c\n"   /* print stacktrace */
                         ":R\n"     /* Detach */
                         "\\$q\n"   /* Quit */
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
#elif defined(Q_OS_INTEGRITY)
    /* abort */
    CheckSuccess(Failure);
#else /* All other platforms */
    /*
     * TODO: SCO/UnixWare 7 must be something like (not tested)
     *  debug -i c <pid> <<EOF\nstack -f 4\nquit\nEOF\n
     */
# if !defined(__GNUC__)
    if(backtrace_command(outb, "dbx %s %d 2>/dev/null <<EOF\n"
                         "where\n"
                         "detach\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
# endif
    if(backtrace_command(outb, "gdb -q %s %d 2>/dev/null <<EOF\n"
                         "set prompt\n"
                         "where\n"
#if 0
                         "echo ---\\n\n"
                         "frame 4\n"
                         "set \\$x = 50\n"
                         "while (\\$x)\n"
                         "info locals\n"
                         "up\n"
                         "set \\$x--\n"
                         "end\n"
                         "echo ---\\n\n"
#endif
                         "detach\n"
                         "quit\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
#endif
    const char debug_err[] = "No debugger found\n";
    fwrite(debug_err, strlen(debug_err), 1, outb);
}
예제 #2
0
static void print_backtrace(FILE *outb)
{
    /*
     * In general dbx seems to do a better job than gdb.
     *
     * Different dbx implementations require different flags/commands.
     */

#if defined(Q_OS_FREEBSD)
    /*
     * FreeBSD insists on sending a SIGSTOP to the process we
     * attach to, so we let the debugger send a SIGCONT to that
     * process after we have detached.
     */
    if(backtrace_command(outb, "gdb -q %s %d 2>/dev/null <<EOF\n"
                         "set prompt\n"
                         "where\n"
                         "detach\n"
                         "shell kill -CONT %d\n"
                         "quit\n"
                         "EOF\n",
                         globalProgName, (int)getpid(), (int)getpid()))
        return;
#elif defined(Q_OS_HPUX)
    /*
     * HP decided to call their debugger xdb.
     *
     * This does not seem to work properly yet. The debugger says
     * "Note: Stack traces may not be possible until you are
     *  stopped in user code." on HP-UX 09.01
     *
     * -L = line-oriented interface.
     * "T [depth]" gives a stacktrace with local variables.
     * The final "y" is confirmation to the quit command.
     */
    if(backtrace_command(outb, "xdb -P %d -L %s 2>&1 <<EOF\n"
                         "T 50\n"
                         "q\ny\n"
                         "EOF\n",
                         (int)getpid(), globalProgName))
        return;
    if(backtrace_command(outb, "gdb -q %s %d 2>/dev/null <<EOF\n"
                         "set prompt\n"
                         "where\n"
                         "detach\n"
                         "quit\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;

#elif defined(Q_OS_SOLARIS)
    if(backtrace_command(outb, "dbx %s %d 2>/dev/null <<EOF\n"
                         "where\n"
                         "detach\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
    if(backtrace_command(outb, "gdb -q %s %d 2>/dev/null <<EOF\n"
                         "set prompt\n"
                         "where\n"
                         "echo ---\\n\n"
                         "frame 5\n"      /* Skip signal handler frames */
                         "set \\$x = 50\n"
                         "while (\\$x)\n" /* Print local variables for each frame */
                         "info locals\n"
                         "up\n"
                         "set \\$x--\n"
                         "end\n"
                         "echo ---\\n\n"
                         "detach\n"
                         "quit\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
    if(backtrace_command(outb, "/usr/proc/bin/pstack %d",
                         (int)getpid()))
        return;
    /*
     * Other Unices (AIX, HPUX, SCO) also have adb, but
     * they seem unable to attach to a running process.)
     */
    if(backtrace_command(outb, "adb %s 2>&1 <<EOF\n"
                         "0t%d:A\n" /* Attach to pid */
                         "\\$c\n"   /* print stacktrace */
                         ":R\n"     /* Detach */
                         "\\$q\n"   /* Quit */
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;

#else /* All other platforms */
    /*
     * TODO: SCO/UnixWare 7 must be something like (not tested)
     *  debug -i c <pid> <<EOF\nstack -f 4\nquit\nEOF\n
     */
# if !defined(__GNUC__)
    if(backtrace_command(outb, "dbx %s %d 2>/dev/null <<EOF\n"
                         "where\n"
                         "detach\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
# endif
    if(backtrace_command(outb, "gdb -q %s %d 2>/dev/null <<EOF\n"
                         "set prompt\n"
                         "where\n"
                         "detach\n"
                         "quit\n"
                         "EOF\n",
                         globalProgName, (int)getpid()))
        return;
#endif
    const char debug_err[] = "No debugger found\n";
    fwrite(debug_err, strlen(debug_err), 1, outb);
}