2012-02-01 12 views
36

Sto eseguendo tomcat 5.5 su x86_64 CentOS 5.7 utilizzando Oracle Java 1.6.0 a 32 bit.jstack - file noto non è sicuro

Processo JVM utilizzato da tomcat con 6421 pid. Tomcat sta funzionando bene.

Quando viene eseguito jstack non riesce con:

[[email protected] ~]# jstack 6421 
6421: well-known file is not secure 

per ottenere qualsiasi uscita ragionevole, ho bisogno di usare l'opzione forza:

[[email protected] ~]# jstack -F 6421 
Attaching to process ID 6421, please wait... 
Debugger attached successfully. 
Server compiler detected. 
JVM version is 17.0-b16 
Deadlock Detection: 

No deadlocks found. 
(...) 

Le domande sono:

  1. che cosa fa il messaggio di errore "file noto i s non sicuro " significa?
  2. qual è il file "noto"?
  3. perché/quando il comando jstack non funziona senza un'opzione di forzatura?

Grazie in anticipo.

+0

Per quanto tempo è stato in esecuzione Tomcat? CentOS/RHEL cancella inutilmente i file da/tmp dopo alcuni giorni (non ricordo quanti). –

+0

@PaulCager: ho riavviato circa 1 minuto prima di eseguire 'jstack' –

+1

Lo stesso si applica all'esecuzione di' jmap' per eseguire un dump dell'heap. –

risposta

29

Ciò è probabilmente dovuto al file in/tmp usato per comunicare con il procedimento avente autorizzazioni diverse rispetto a quella del jstack ottiene. Il file in questione è/tmp/hsperfdata_ $ USER/$ PID.

Non so perché funziona con -F come la pagina man dice "Forza un dump dello stack quando 'jstack [-l] pid' non risponde."

+6

Ho avuto lo stesso problema, perché non ero nello stesso gruppo del file hsperfdata *. Cambiare il mio gruppo tramite "newgrp other-group" ha funzionato. –

+0

Sono in esecuzione come utente root. Esecuzione jstack o jcmd e stampa ancora lo stesso messaggio. C'è una cartella/tmp/hsperfdata_root/pid e ha accesso. – dmachop

+3

@dmachop L'uid: gid utilizzato per eseguire 'jstack' deve corrispondere al gid uid del file noto. L'esecuzione come root non sovrascrive il controllo - puoi 'sudo -u youruser -g yourgroup jstack ...' per diventare l'uid corretto: gid. – Nick

20

Quando si utilizza -F, il JVM sarà congelato.

Se è possibile trovare il file: /tmp/hsperfdata_$USER/$PID. Basta provare a passare a $USER e quindi a exec jstack. Si sta eseguendo con "root", ma tale processo potrebbe non appartenere a root.

se $USER non ha una shell di accesso (ad es.utenti demone), e quindi non è possibile passare a quell'utente, è possibile aggirare il problema utilizzando sudo -u $USER jstack $PID

+10

se $ USER non ha una shell di login (cioè utenti daemon), e quindi non può passare a quell'utente, è possibile aggirare questo usando 'sudo -u $ USER jstack $ PID'. –

3

Vorrei solo aggiungere che potrebbe essere necessario specificare la directory/tmp in base all'opzione -J, poiché non tutte le app utilizzare la quella di default

jstack -J-Djava.io.tmpdir=PATH -l PID 
1

mi è stato sempre lo stesso errore in esecuzione:

watch -n .5 "jstack 26259" 

facendo come sudo funziona:

sudo watch -n .5 "jstack 26259" 
1

Se non si vuole preoccupare di utenti e può lavorare come root e stai bene di uccidere il processo, è possibile utilizzare questo ultimo ricorso:

kill -s SIGQUIT $PID 

Questo scriverà il dump thread per il registro console , per esempio, in caso di Tomcat, che richiederebbe grep per "Discussione completo" che è l'inizio della discarica filo in logs/catalina.out e quindi ottenere il file tdump come:

DUMP_IDX=`grep -n 'Full thread' logs/catalina.out | tail -1 | cut -d':' -f1` 
sed -n $DUMP_IDX,1000000000000000000p logs/catalina.out > jstack-kill-thread-dump-0309.tdump 
5

ho avuto questa problema quando ho provato a eseguire jstack come root.

Una volta passato a un altro utente, ha funzionato immediatamente.

+1

Sì, questo ha funzionato per me. Esegui la mia applicazione (jvmtop) come lo stesso utente in cui è in esecuzione il processo java e il messaggio di errore e l'errore sono andati via ... – rogerdpack

0

Questo è l'uno di linea che uso per assicurarsi che sto utilizzando sempre le autorizzazioni utente corrette:

proc="my-process-name"; pid=`pgrep -f "${proc}"`; sudo -u "#`ps axo uid,pid | grep "${pid}" | tr -s " " | cut -f2 -d" "`" /usr/bin/jstack -l "${pid}" > /mnt/dumps/"${proc}"-`date +%s`.txt 
0

Probabilmente il modo più semplice è:

vedere il proprietario del processo attraverso il ps -ef | grep "nome processo"

quindi passare a quell'utente ed eseguire il comando.

jcmd PID GC.run o qualsiasi altra utilità java

Una cosa che ho notato che nessuno ha discusso qui è; devi anche avere il set di variabili JAVA_HOME. controllare questo da echo $ JAVA_HOME