Beispiel #1
0
      void traceqc()
#endif
{
      void U_STACK_TRACE();       /* somewhere in Fortran RTL */
      U_STACK_TRACE();
      return;
}
/*************************************************************************
 * StackTrace
 */
void StackTrace(char *gdb_command_file)
{
#if defined(PLATFORM_UNIX)
  /*
   * In general dbx seems to do a better job than gdb.
   *
   * Different dbx implementations require different flags/commands.
   */

# if defined(PLATFORM_AIX)

  if (DumpStack("dbx -a %d 2>/dev/null <<EOF\n"
		"where\n"
		"detach\n"
		"EOF\n",
		(int)getpid()))
    return;

  if (DumpStack("gdb -q %s %d 2>/dev/null <<EOF\n"
		"set prompt\n"
		"where\n"
		"detach\n"
		"quit\n"
		"EOF\n",
		global_progname, (int)getpid()))
    return;

# elif defined(PLATFORM_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 (DumpStack("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",
		global_progname, (int)getpid(), (int)getpid()))
    return;

# elif defined(PLATFORM_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 (DumpStack("xdb -P %d -L %s 2>&1 <<EOF\n"
		"T 50\n"
		"q\ny\n"
		"EOF\n",
		(int)getpid(), global_progname))
    return;

  if (DumpStack("gdb -q %s %d 2>/dev/null <<EOF\n"
		"set prompt\n"
		"where\n"
		"detach\n"
		"quit\n"
		"EOF\n",
		global_progname, (int)getpid()))
    return;

#  if defined(PLATFORM_HPUX) && defined(USE_BUILTIN)
  U_STACK_TRACE();
  return;
#  endif

# elif defined(PLATFORM_IRIX)

  /*
   * "set $page=0" drops hold mode
   * "dump ." displays the contents of the variables
   */
  if (DumpStack("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_BUILTIN)
  if (trace_back_stack_and_print())
    return;
#  endif

  if (DumpStack("gdb -q %s %d 2>/dev/null <<EOF\n"
		"set prompt\n"
		"echo --- Stacktrace\\n\n"
		"where\n"
		"echo --- Symbols\\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",
		global_progname, (int)getpid()))
    return;

# elif defined(PLATFORM_OSF)

  if (DumpStack("dbx -pid %d %s 2>/dev/null <<EOF\n"
		"where\n"
		"detach\n"
		"quit\n"
		"EOF\n",
		(int)getpid(), global_progname))
    return;

  if (DumpStack("gdb -q %s %d 2>/dev/null <<EOF\n"
		"set prompt\n"
		"where\n"
		"detach\n"
		"quit\n"
		"EOF\n",
		global_progname, (int)getpid()))
    return;

# elif defined(PLATFORM_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 (DumpStack("dbx %s %d 2>/dev/null <<EOF\n"
		"where\n"
		"quit\nEOF\n",
		global_progname, (int)getpid()))
    return;

  if (DumpStack("gdb -q %s %d 2>/dev/null <<EOF\n"
		"set prompt\n"
		"where\n"
		"detach\n"
		"quit\n"
		"EOF\n",
		global_progname, (int)getpid()))
    return;

# elif defined(PLATFORM_SOLARIS)

  if (DumpStack("dbx %s %d 2>/dev/null <<EOF\n"
		"where\n"
		"detach\n"
		"EOF\n",
		global_progname, (int)getpid()))
    return;

  if (DumpStack("gdb -q %s %d 2>/dev/null <<EOF\n"
		"set prompt\n"
		"echo --- Stacktrace\\n\n"
		"where\n"
		"echo --- Symbols\\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",
		global_progname, (int)getpid()))
    return;

  if (DumpStack("/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 (DumpStack("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",
		global_progname, (int)getpid()))
    return;

# else /* All other Unix 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 (DumpStack("dbx %s %d 2>/dev/null <<EOF\n"
		"where\n"
		"detach\n"
		"EOF\n",
		global_progname, (int)getpid()))
    return;
#  endif

  // This version works (piping from a file)
  if (DumpStack("gdb -q %s %d 2>/dev/null <%s >fweelin-stackdump",
		global_progname, (int)getpid(), gdb_command_file))
    return;

#if 0
  // This version does not work (piping from stdin)
  if (DumpStack("gdb -q %s %d 2>/dev/null <<EOF\n"
		"set prompt\n"
		"echo --- Stacktrace\\n\n"
		"where\n"
		"echo --- Symbols\\n\n"
		"frame 4\n"
		"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",
		global_progname, (int)getpid()))
    return;
#endif

# endif

# if defined(__GNUC__) && defined(USE_BUILTIN)

  GCC_DumpStack();

# endif

  write(global_output,
	"No debugger found\n", strlen("No debugger found\n"));

#elif defined(PLATFORM_WIN32)
  /* Use StackWalk() */
#endif
}