2016-05-18 44 views
6

Per supportare una migliore profilazione dei dati, vorrei che il mio agente JVMTI abilitasse un paio di flag JVM. L'agente in questione è Honest-Profiler ed è può essere caricato solo all'avvio.Come può l'agente JVMTI impostare un flag JVM all'avvio?

vorrei abilitare le bandiere: -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints

Secondo problema documentato here se le bandiere non sono sulla otteniamo un profilo parziale. Sarebbe bello andare oltre a mettere in guardia l'utente e abilitare la bandiera.

+2

Se non hai trovato una soluzione legale, c'è un approccio cruento da @apangin: https://github.com/odnoklassniki/one-elf/blob/master/test/one/jvm/HotspotFlags.java che stabilisce l'indirizzo di ha caricato libjvm.so e calcola l'indirizzo flag dall'indirizzo .so + .symtab offset costante (ma non sempre funziona, dipende dall'utilizzo concreto di flag nel codice VM) – qwwdfsad

risposta

8

Per quanto riguarda DebugNonSafepoints che non hanno nemmeno bisogno di impostare questo flag. Guardate debugInfoRec.cpp:

static inline bool compute_recording_non_safepoints() { 
    if (JvmtiExport::should_post_compiled_method_load() 
     && FLAG_IS_DEFAULT(DebugNonSafepoints)) { 
    // The default value of this flag is taken to be true, 
    // if JVMTI is looking at nmethod codes. 
    // We anticipate that JVMTI may wish to participate in profiling. 
    return true; 
    } 

    // If the flag is set manually, use it, whether true or false. 
    // Otherwise, if JVMTI is not in the picture, use the default setting. 
    // (This is true in debug, just for the exercise, false in product mode.) 
    return DebugNonSafepoints; 
} 

Se il flag non è impostato, informazioni di debug è ancora registrato quando JVMTI CompiledMethodLoad notifiche sono abilitate. Devi solo richiedere la funzionalità can_generate_compiled_method_load_events e attivare le notifiche JVMTI_EVENT_COMPILED_METHOD_LOAD.

che è esattamente come gestire nel mio progetto async-profiler.


Non esiste un modo sicuro per modificare i flag JVM non gestibili in fase di esecuzione. Tuttavia, c'è un brutto trucco per farlo su Linux.

  1. Leggere /proc/self/maps per trovare l'indirizzo di base di libjvm.so.
  2. Utilizzare ELF format reader per scoprire un offset del simbolo desiderato nella libreria dinamica.
  3. Scrivere direttamente all'indirizzo di questo simbolo.

Ecco a sample code per questo trucco.

+0

L'ho gestito tramite Helfy (e anche con Hotspot SA). Lo mostrerò con un codice di esempio quando lo ho preparato –

+1

qui è https://github.com/serkan-ozal/jvm-playground/blob/master/src/main/java/tr/com/serkanozal/jvm/ parco giochi/ChangeImmutableVmFlagDemo.java –

+0

@ SerkanÖzal Cool! Non pensavo che Helfy potesse essere usato per quello. Ti dispiacerebbe aggiungere questo esempio al repository Helfy su github? – apangin

1

Ok, questo non è una risposta precisa, ma più di una gomitata in certa direzione ....

In services/writeableFlags.hpp ci sono metodi statici per l'impostazione bandiere VM. Il successo dipenderà dal fatto che questi flag siano effettivamente mutabili ma sarebbe il posto giusto per iniziare a dare un'occhiata. Non ho provato a chiamare questi metodi dall'agente JVMTI ma, teoricamente, dovrebbe funzionare.