Estoy pensando en crear una herramienta de depuración para mi aplicación Java.

Me estoy preguntando si es posible obtener una traza de la pila, como Exception.printStackTrace() pero sin llegar a lanzar una excepción?

Mi objetivo es, en cualquier método, volcado de la pila a ver quién es el método llamador.

  • Probablemente es mejor utilizar una herramienta de depuración. Hay muchos de ellos por ahí, y usted puede dedicar ese tiempo a trabajar en el proyecto en lugar de reinventar algo. A menos que usted está teniendo diversión escribir un depurador, por supuesto.
InformationsquelleAutor corgrath | 2009-06-03

9 Comentarios

  1. 78

    También puede intentar Thread.getAllStackTraces() para obtener un mapa de los seguimientos de pila de todos los hilos que están vivos.

    • +1, sin duda muy útil si se quiere analizar el seguimiento de pila!
  2. 219

    Sí, simplemente uso

    Thread.dumpStack()
    • …pero no tirarlo.
    • Esa es la respuesta que en realidad se aborda la cuestión.
    • Muy simple y elegante. Esto debería haber sido aceptado respuesta.
    • Fwiw, el origen de este método: public static void dumpStack() { new Exception("Stack trace").printStackTrace(); }
  3. 39

    Si quieres la traza para el subproceso actual (en lugar de todos los hilos en el sistema, como la sugerencia de Ram no), hacer:

    Hilo.currentThread().getStackTrace()

    Para encontrar a la persona que llama, do:

    private String getCallingMethodName() {
        StackTraceElement callingFrame = Thread.currentThread().getStackTrace()[4];
        return callingFrame.getMethodName();
    }

    Y llamar a ese método desde dentro del método que necesita saber quién es su llamador. Sin embargo, una palabra de advertencia: el índice de la vocación marco dentro de la lista podría variar de acuerdo a la JVM! Todo depende de cómo muchas capas de llamadas existen dentro de getStackTrace antes de llegar al punto donde la traza se genera. Una solución más eficaz sería la de obtener la traza, y iterar a través de ella se busca el marco de getCallingMethodName, luego tome dos pasos más hasta encontrar el verdadero autor de la llamada.

    • Tan sólo tienes que crear una nueva Excepción en su propio y utilizar [1] como el índice!
    • El título de esta pregunta dice «sin lanzar una excepción». Concedido, te sugerimos la creación de la excepción, pero no tirarlo, pero yo todavía creo que no es en el espíritu de la pregunta.
    • Por supuesto que lo es. La creación de una Excepción es el más bajonivel manera de conseguir un stacktrace. Incluso tu Hilo.currentThread().getStackTrace() no se, pero a mi manera lo hace más rápido :).
    • Hay otra consideración: con muchos marcos de las pruebas, por ejemplo, Spock, sólo la creación de una Excepción (sin tirar de ella) será suficiente para que el marco para recoger en: la prueba se considerará que una Excepción se ha «producido» y el examen final, con un error.
    • Estás seguro? Spock tendría que utilizar agentes para hacer eso. Pero de todos modos, porque yo sólo tenía que llamar a la clase I se utiliza la Reflexión.getCallerClass(2) en una función de utilidad. Usted no va a obtener la función y el número de línea de esa manera, el pensamiento.
  4. 33

    Usted puede obtener una traza de la pila como este:

    Throwable t = new Throwable();
    t.printStackTrace();

    Si quieres acceder a la trama, puede utilizar t.getStackTrace() para obtener un conjunto de marcos de pila.

    Ser conscientes de que este stacktrace (como cualquier otro) puede ser que faltan algunos de los marcos si el compilador hotspot se ha ocupado de la optimización de las cosas.

    • Me gusta esta respuesta porque me ofrece la oportunidad para dirigir la salida. Puedo reemplazar t.printStackTrace con t.printStackTrace(System.out).
    • En una línea: new Throwable().printStackTrace(System.out);
    • Esto debe ser aceptado respuesta. Es simple y sencillo! Gracias por compartir
    • y es fácil para enviar a java.util.Registrador de log.log(Level.SEVERE, "Failed to do something", new Throwable());
    • 2019 recién llegados upvote
  5. 13

    Aviso de que el Hilo.dumpStack() en realidad, se produce una excepción:

    new Exception("Stack trace").printStackTrace();
    • Crea una excepción, pero no tirarlo.
  6. 6

    Usted también puede enviar una señal a la JVM para ejecutar Hilo.getAllStackTraces() en una ejecución de Java proceso mediante el envío de una señal de SALIR para el proceso.

    En Unix/Linux uso:

    kill -QUIT process_id, donde identificador_de_proceso es el número de proceso de su programa de Java.

    En Windows, puede presionar Ctrl-Break en la aplicación, aunque por lo general no ver esto a menos que usted está ejecutando un proceso de consola.

    JDK6 introdujo otra opción, la jstack de comandos, la cual muestra la pila de ejecución JDK6 proceso en el equipo:

    jstack [-l] <pid>

    Estas opciones son muy útiles para aplicaciones que se ejecutan en un entorno de producción y no puede ser modificado fácilmente. Son especialmente útiles para el diagnóstico de tiempo de ejecución de interbloqueos o problemas de rendimiento.

    http://java.sun.com/developer/technicalArticles/Programming/Stacktrace/
    http://java.sun.com/javase/6/docs/technotes/tools/share/jstack.html

  7. 4

    Si usted necesita salida de la captura de

    StringWriter sw = new StringWriter();
    new Throwable("").printStackTrace(new PrintWriter(sw));
    String stackTrace = sw.toString();
  8. 4

    Java 9 introdujo el StackWalker y clases de apoyo para caminar la pila.

    Aquí hay un par de fragmentos de la Javadoc:

    La pie método abre una serie secuencial de entorno de pila para el subproceso actual y, a continuación, se aplica la función dada a pie de la StackFrame corriente. La secuencia de informes del marco de pila de elementos en orden, desde la parte superior de la mayoría de marco que representa la ejecución en el punto en el que la pila se ha generado para la parte inferior de la mayoría de marco. El StackFrame secuencia se cierra cuando el pie método devuelve. Si se realiza un intento de reutilizar el cerrado de corriente, IllegalStateException será lanzado.

    1. Instantánea el top 10 de los marcos de pila del subproceso actual,

      List<StackFrame> stack = StackWalker.getInstance().walk(s ->
       s.limit(10).collect(Collectors.toList()));
  9. 0

    HPROF Java Profiler

    Usted incluso no tiene que hacer esto en el código. Puede adjuntar el Java HPROF a su proceso y en cualquier momento, pulse Control-\ a la salida de volcado del montón, la ejecución de los hilos, etc . . . sin ensuciar su código de la aplicación. Esto es un poco anticuado, Java 6 viene con la interfaz gráfica de usuario jconsole, pero me sigue pareciendo HPROF a ser muy útil.

Dejar respuesta

Please enter your comment!
Please enter your name here