Pergunta

Gostaria de alguma forma log cada vez Thread.interrupt() é chamado, o registro que Tópico emitiu a chamada (e sua pilha atual), bem como informações de identificação sobre qual thread está sendo interrompido.

Existe uma maneira de fazer isso? Busca de informações, vi alguém de referência a possibilidade de implementação de um gestor de segurança. Isto é algo que pode ser feito em tempo de execução (por exemplo, em um cliente Applet ou Web Start), ou você precisa de ferramentas do JVM instalado para fazer isso?

Ou há uma maneira melhor de fazer isso?

Foi útil?

Solução

Como um corte rápido, este foi um muito mais fácil de fazer do que eu pensava que seria. Como este é um corte rápido, eu não fazer coisas como garantir que o rastreio da pilha é suficiente fundo antes dereferencing a matriz, etc. I inserido o seguinte no meu construtor do Applet assinado:

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);
      }
    });

eo método dumpThreadStack é o seguinte:

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());
}

Eu nunca poderia, é claro, deixar este no código de produção, mas suficiente para me dizer exatamente qual thread estava causando um interrupt() que eu não esperava. Isto é, com esse código no lugar, eu obter um despejo de pilha para cada chamada para Thread.interrupt().

Outras dicas

Antes de tentar nada muito selvagem, você já pensou em usar a Java depuração API? Eu acho que MethodEntryEvents captura sobre Thread.interrupt () iria fazê-lo.

Eeek, essa é a interface antiga, você também deve verificar oout o novo JVM Tool interface .

Eu olhava para AspectJ e as suas capacidades para embrulhar chamadas de método. Um execução pointcut volta o método interrupt() deve ajudar aqui.

Note que desde que você está olhando para interceptar uma chamada de método sistema Java (ao contrário de seu código de aplicativo), o acima pode não ser adequado. Esta discussão parece sugerir que é possível, mas nota que ele é criou um tecido rt.jar.

Como já foi dito ... Se é uma coisa de uma vez JVMTI é provavelmente a forma mais grave de ir. No entanto, apenas como diversão poderia ser usar a biblioteca asm e as APIs de instrumentação para criar um agente que insere uma chamada para um método estático que você criou apenas antes da chamada Thread.interrupt () (ou talvez altera o Thread.interrupt ( ) método para fazer o mesmo, eu acho que você pode fazer isso).

Ambos leva algum tempo para aprender, mas é muito divertido trabalhar com e uma vez que você começa a preensão de que você pode usá-los para todos os tipos de coisas engraçadas no futuro :-) Eu realmente não tem nenhum bons trechos para colar aqui agora, mas se você google em torno de ASM e talvez olhar para o JIP por algum uso criativo de ASM Eu acho que você vai encontrar inspiração.

JIP: Java interativo Profiler

Você poderia tentar também com JMX:

ManagementFactory.getThreadMXBean().getThreadInfo(aThreadID)

ThreadInfo objeto que você pode fazer logon:

  • o rastreamento de pilha do thread
  • informações gerais userful como nome, status, etc
  • etc

Editar

uso getAllThreadIds (), a fim de obter a lista de ids de rosca ao vivo:

long[] ids = ManagementFactory.getThreadMXBean().getAllThreadIds();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top