Pergunta

Estou escrevendo um criador de perfil curto e simples (em C), que tem como objetivo imprimir rastreamentos de pilha para threads em vários clientes Java em intervalos regulares.Eu tenho que usar a função não documentada AsyncGetCallTrace em vez de GetStackTrace para minimizar a intrusão e permitir rastreamentos de pilha, independentemente do estado do thread.O código fonte da função pode ser encontrado aqui: http://download.java.net/openjdk/jdk6/promoted/b20/openjdk-6-src-b20-21_jun_2010.tar.gzem hotspot/src/share/vm/prims/forte.cpp.Encontrei algumas páginas de manual documentando JVMTI, manipulação de sinal e tempo, bem como um blog com detalhes sobre como configurar a chamada AsyncGetCallTrace:http://jeremymanson.blogspot.com/2007/05/profiling-with-jvmtijvmpi-sigprof-and.html.

O que falta neste blog é o código para realmente invocar a função dentro do manipulador de sinal (o autor assume que o leitor pode fazer isso sozinho).Peço ajuda para fazer exatamente isso.Não tenho certeza de como e onde criar a estrutura ASGCT_CallTrace (e a estrutura interna ASGCT_CallFrame), conforme definido no arquivo forte.cpp acima mencionado.A struct ASGCT_CallTrace é um dos parâmetros passados ​​para AsyncGetCallTrace, então preciso criá-la, mas não sei como obter os valores corretos para seus campos:JNIEnv *env_id, jint num_frames e JVMPI_CallFrame quadros.Além disso, não sei qual é o terceiro parâmetro passado para AsyncGetCallTrace (void ucontext) deveria ser?

O problema acima é o principal que estou tendo.No entanto, outros problemas que enfrento incluem:[1] SIGPROF não parece ser acionado pelo cronômetro exatamente nos intervalos especificados, mas com um pouco menos de frequência.Ou seja, se eu definir o temporizador para enviar um SIGPROF a cada segundo (1 seg, 0 usec), então em uma execução de 5 segundos, estou recebendo menos de 5 saídas do manipulador SIGPROF (geralmente 1-3) [2] As saídas do manipulador SIGPROF não aparecem durante um Thread.sleep no código Java.Portanto, se um SIGPROF for enviado a cada segundo e eu tiver Thread.sleep(5000);, não receberei nenhuma saída do manipulador durante a execução desse código.

Qualquer ajuda seria apreciada.Detalhes adicionais (bem como partes do código e exemplos de resultados) serão publicados mediante solicitação.

Obrigado!

Foi útil?

Solução

Finalmente consegui um resultado positivo, mas como pouca discussão foi gerada aqui, minha resposta será breve.

A estrutura ASGCT_CallTrace (e o array ASGCT_CallFrame subjacente) pode simplesmente ser declarada no manipulador de sinal, existindo assim apenas a pilha:Rastreamento ASGCT_CallTrace;JNIEnv *env;global_VM_pointer->AttachCurrentThread((void **) &env, NULL);trace.env_id = env;trace.num_frames = 0;Armazenamento ASGCT_CallFrame[25];trace.frames = armazenamento;

O seguinte obtém o uContext:ucontext_t uContext;getcontext(&uContext);

E então a ligação é apenas:AsyncGetCallTrace(&trace, 25, &uContext);

Tenho certeza de que há algumas outras nuances que tive que cuidar no processo, mas na verdade não as documentei.Não tenho certeza se posso divulgar o código atual completo que possuo, que solicita e obtém rastreamentos de pilha de qualquer programa Java de forma assíncrona e com êxito em intervalos fixos.Mas se alguém estiver interessado ou preso no mesmo problema, agora posso ajudar (eu acho).

Nas outras duas questões:[1] Se um thread estiver inativo e um SIGPROF for gerado, o thread tratará esse sinal somente após acordar.Isso é normal, pois é função do thread manipular o sinal.[2] As imperfeições do temporizador parecem não aparecer mais.Talvez eu tenha medido mal.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top