Qui l'agente java si collega al segnale SIGQUIT. Vorrei evitarlo, perché quello è lo stesso segnale che la JVM usa per scrivere un dump di thread su stdout. Voglio evitare quella doppiezza.
è sufficiente rimuovere il seguente frammento dal codice
/* Set callbacks and enable event notifications */
memset(&callbacks, 0, sizeof(callbacks));
callbacks.DataDumpRequest = &dumpThreadInfo;
err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
CHECK_JVMTI_ERROR(jvmti, err);
err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,JVMTI_EVENT_DATA_DUMP_REQUEST, NULL);
CHECK_JVMTI_ERROR(jvmti, err);
mi piacerebbe o allegare a un segnale diverso
Here is la carta, che è un po 'vecchio, ma l'informazione dovrebbe essere ancora rilevante.
solo un esempio di come fare una gestione
import sun.misc.Signal;
import sun.misc.SignalHandler;
public class ThreadDumpSignalHandler implements SignalHandler {
private volatile SignalHandler old;
private ThreadDumpSignalHandler() {
}
public static void register(String sigName) {
ThreadDumpSignalHandler h = new ThreadDumpSignalHandler();
h.old = Signal.handle(new Signal(sigName), h)
}
public void handle(Signal sig) {
threadDump();
if(old != null && old != SIG_DFL && old != SIG_IGN) {
old.handle(sig);
}
}
// call your own threadDump native method.
// note that in the implementation of this method you are able to access jvmtiEnv from *gdata (see below)
private native void threadDump();
}
ThreadDumpSignalHandler.register("INT");
Di causa è possibile scrivere gestore di segnale completamente nativa del segnale (si ricorda che non ho ancora testato, questo è solo un'idea che dovrebbe funzionare)
static sighandler_t old_handler;
static void thread_dump_handler(int signum) {
if(gdata && gdata->jvmti) {
... get thread dump
}
if(old_handler) {
old_handler(signum);
}
}
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
old_handler = signal(SIGINT, thread_dump_handler);
...
}
o trovare un modo per l'agente di generare periodicamente un dump thread.
Nel vostro campione c'è globale * GData
typedef struct {
/* JVMTI Environment */
jvmtiEnv *jvmti;
jboolean vm_is_started;
/* Data access Lock */
jrawMonitorID lock;
} GlobalAgentData;
static GlobalAgentData *gdata;
... così, basta ottenere jvmtiEnv da lì in qualsiasi momento si desidera (callback del timer, etc.)
Nessuno degli eventi in jvmtiEventCallbacks sembra adatto (a meno che non si desideri utilizzare DataDumpRequestion, ma se lo si è fatto, non si chiederebbe qui :)). Sembra che tu stia meglio se il tuo agente chiama direttamente "GetStackTrace". C'è una ragione per cui non puoi farlo? –
@ Paul-Hicks, potresti pubblicare un link o un codice su come collegarmi al jvm in questo caso? – Ovesh
Hai inserito l'agente dll o .so nel tuo jag -agentpath o lo definisci come -agentlib. Dai un'occhiata a [questa risposta] (http://stackoverflow.com/a/173447/3195526) o [Pagina di introduzione di IBM] (http://publib.boulder.ibm.com/infocenter/realtime/v2r0/index. jsp? topic =% 2Fcom.ibm.rt.doc.20% 2Fdiag% 2Ftools% 2Fjvmti.html). E 'questo quello che volevi sapere? Devo trasformare questo in una risposta? –