Frage

Ich mag irgendwie jedes Mal einloggen Thread.interrupt() genannt wird, Protokollierung, das Thema den Anruf ausgegeben (und dessen aktuellen Stack) sowie identifizierende Informationen über den Thread unterbrochen wird.

Gibt es eine Möglichkeit, dies zu tun? Die Suche nach Informationen, sah ich jemand die Möglichkeit der Implementierung eines Sicherheitsmanagers verweisen. Ist das etwas, das zur Laufzeit durchgeführt werden kann (beispielsweise in einem Applet oder Web Start-Client), oder müssen Sie die installierte JVM Werkzeug, dies zu tun?

Oder gibt es einen besseren Weg, dies zu tun?

War es hilfreich?

Lösung

Als schneller Hack war dies ein Los leichter zu tun, als ich dachte, es wäre. Da dies eine schnelle Hack ist, tat ich nicht Dinge wie sicher, dass der Stack-Trace tief genug ist, bevor das Array dereferencing usw. ich folgend in meinem signierten Applet Konstruktor eingefügt:

log.info("Old security manager = " + System.getSecurityManager());
System.setSecurityManager(new SecurityManager() {
      @Override
      public void checkAccess(final Thread t) {
        StackTraceElement[] list = Thread.currentThread().getStackTrace();
        StackTraceElement element = list[3];
        if (element.getMethodName().equals("interrupt")) {
          log.info("CheckAccess to interrupt(Thread = " + t.getName() + ") - "
                   + element.getMethodName());
          dumpThreadStack(Thread.currentThread());
        }
        super.checkAccess(t);
      }
    });

und die dumpThreadStack Methode ist wie folgt:

public static void dumpThreadStack(final Thread thread) {
  StringBuilder builder = new StringBuilder('\n');
  try {
    for (StackTraceElement element : thread.getStackTrace()) {
      builder.append(element.toString()).append('\n');
    }
  } catch (SecurityException e) { /* ignore */ }
  log.info(builder.toString());
}

Ich kann nie, natürlich, verlassen diese in der Produktion Code, aber es genügt mir genau zu sagen, welcher Thread ein interrupt() verursacht wurde, die ich nicht erwartet habe. Das heißt, mit diesem Code an Ort und Stelle, ich einen Stack Dump für jeden Anruf zu Thread.interrupt() erhalten.

Andere Tipps

Bevor etwas zu wild versuchen, haben Sie darüber nachgedacht, mit dem Java Debugging API ? Ich würde denken, dass die Erfassung MethodEntryEvents auf Thread.interrupt () würde es tun.

Eeek, das ist die alte Schnittstelle, sollten Sie auch die neue überprüfen Außen-Ø JVM-Tool Schnittstelle .

Ich würde Blick auf AspectJ und seine Fähigkeiten Methodenaufrufe zu wickeln. Eine Ausführung pointcut um die interrupt() Methode sollte hier helfen.

Beachten Sie, dass seit Sie suchen einen Java-System Methodenaufruf abfangen (im Gegensatz zu dem Anwendungscode im Gegensatz), die über kann nicht geeignet sein. Dieser Thread scheint es möglich vorzuschlagen, aber beachten Sie, dass er a erstellt gewebt rt.jar.

Wie andere gesagt haben ... Wenn es sich um eine einmalige Sache JVMTI ist wahrscheinlich die meisten Hardcore-Weg zu gehen. Allerdings könnte genauso viel Spaß, die asm-Bibliothek und die Instrumentierung APIs zu verwenden, um ein Mittel zu schaffen, die einen Aufruf einer statischen Methode fügt die Sie erstellt haben kurz vor dem Thread.interrupt () Aufruf (oder vielleicht ändert die Thread.interrupt ( Verfahren), das gleiche zu tun, ich denke, man kann das tun).

Beide dauern einige Zeit zu lernen, aber es ist ganz lustig, mit zu arbeiten und wenn man den Halt davon bekommen können Sie sie für alle Arten von lustigen Dingen in der Zukunft :-) verwenden Ich wirklich keine gute Schnipsel haben jetzt hier einfügen, aber wenn Sie für ASM google herum und vielleicht für einige kreativen Einsatz von ASM am JIP aussehen Ich glaube, Sie Inspiration finden werden.

JIP: Java Interactive Profiler

Sie könnten auch versuchen, mit JMX:

ManagementFactory.getThreadMXBean().getThreadInfo(aThreadID)

mit dem Thread Objekt können Sie sich einloggen:

  • der Stack-Trace des Gewindes
  • allgemeine userful Informationen wie Name, Status, usw.
  • etc

Bearbeiten

Verwendung getAllThreadIds (), um die Liste des Live-Thread-IDs zu erhalten:

long[] ids = ManagementFactory.getThreadMXBean().getAllThreadIds();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top