VisualVM
You can start "jvisualvm" with jdk1.6.0_07 on any master or slave machine so you can attach to the java process.
Hudson Master
We are running Hudson under JBoss Enterprise Application Platform, thus before you start the AS you need to specify debug parameters: export JAVA_OPTS=" -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n" Then just simply point your debugging tool to <hudson_host>:8787. Hudson also has built-in debugging capabilities via Jetty plugin - see http://hudson.gotdns.com/wiki/display/HUDSON/Building+Hudson.
Hudson Slave
To debug this, you need to be able to attach a debugger to the slave, and that means launching slaves with the JPDA support on. For JNLP slaves unfortunately I don't know how to do this, but for slaves that are launched by the master, you can do this by adding something like "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=5005" to the command line. If you see exceptions, be sure to capture that as it's helpful for us to see what the potential problem might have been.
Reference a slave from the groovy console
hudson.model.Hudson.instance.getComputer("dev91-linux").getExecutors()[4] println hudson.model.Hudson.instance.getSlave("dev91-linux").getLabelString() computer = hudson.model.Hudson.instance.getComputer("dev91-linux") //execute groovy command on a slave hudson.util.RemotingDiagnostics.executeGroovy("println \"hallo\"",computer.getChannel()) //find out what's happening in the executor executor = computer.getExecutors()[EXECUTOR_INDEX] println ("Project: "+ executor.executable.getParent() ) println("Stack trace: \n") stack = Thread.getAllStackTraces()[executor] for(i in stack) { println(i) } //who owns SCM lock that blocks the executor? (no null checks!) //if "java.lang.NullPointerException: Cannot get property: parent on null object" then we are not blocked by another SCM operation //if "Cannot invoke method getLock() on null object" - same as well executor.executable.parent.getTriggers().values().each { scmLock=it.getLock(); println "SCM LOCK BY: " + scmLock.owner stack = Thread.getAllStackTraces()[scmLock.owner] for(i in stack) { println(" "+i) } // ... possibly kill the culprit: scmLock.owner.stop() } // reset dead executors execs = computer.executors for(e in execs) { if(!e.isAlive()) { computer.removeExecutor(e) } } computer.setNode( computer.getNode() );
Some more handy groovy scripts
get thread dump of master
In groovy console execute:
for(entry in Thread.getAllStackTraces().entrySet()) { println entry.key for(s in entry.value) println " " + s }
misc
println hudson.model.Hudson.instance.getItem("JBoss-Metadata").workspace.channel t = hudson.model.Hudson.instance.getItem("JBoss-Metadata").getTriggers().get(hudson.triggers.SCMTrigger.DESCRIPTOR).getLock().owner println t stack = Thread.getAllStackTraces()[t] for(p in stack) { println(" "+p) } println "\n\n" for( i in hudson.triggers.SCMTrigger.DESCRIPTOR.getItemsBeingPolled()) { println "PROJECT: " + i println "WORKSPACE CHANNEL: "+i.workspace.channel def k = i.getTriggers().get(hudson.triggers.SCMTrigger.DESCRIPTOR).getLock().owner if(k != null) { println "THREAD: "+k stack2 = Thread.getAllStackTraces()[k] for(l in stack2) { println(" "+l) } } }
Find out which builds were executing during a given time range (builds should not have been deleted):
import java.text.SimpleDateFormat; import java.util.GregorianCalendar; df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); starttime=new GregorianCalendar(); endtime=new GregorianCalendar(); buildEnd=new GregorianCalendar(); //------- look here ------- starttime.setTime(df.parse("2008-5-10 10:10:10")); endtime.setTime(df.parse("2008-5-10 11:10:10")); //------- user settings end ----- for (hudson.model.AbstractProject p : hudson.model.Hudson.instance.projects) { for (hudson.model.AbstractBuild b : p.getBuilds() ) { if (b==null) break; //I think that can't be null anyway if ( b.isBuilding() || b.timestamp.compareTo(endtime) >= 0 ) continue; buildEnd.setTimeInMillis(b.timestamp.getTimeInMillis()+b.duration); if ( buildEnd.compareTo(starttime) < 0 ) break; println b; } }
Comments