提交 19ad2a40 编写于 作者: K kohsuke

improved thread death error diagnostics.


git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@4893 71c3de6d-444a-0410-be80-ed276b4c234a
上级 cb0e27c6
......@@ -27,6 +27,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.lang.management.LockInfo;
import java.lang.management.ManagementFactory;
import java.lang.management.MonitorInfo;
......@@ -622,4 +624,10 @@ public class Functions {
if(b==null) return true;
return b;
}
public static String printThrowable(Throwable t) {
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw));
return sw.toString();
}
}
......@@ -13,7 +13,7 @@ import java.io.IOException;
*
* @author Kohsuke Kawaguchi
*/
public class Executor extends Thread {
public class Executor extends Thread implements ModelObject {
private final Computer owner;
private final Queue queue;
......@@ -25,6 +25,8 @@ public class Executor extends Thread {
private int number;
private Queue.Executable executable;
private Throwable causeOfDeath;
public Executor(Computer owner) {
super("Executor #"+owner.getExecutors().size()+" for "+owner.getDisplayName());
this.owner = owner;
......@@ -34,36 +36,44 @@ public class Executor extends Thread {
}
public void run() {
while(true) {
if(Hudson.getInstance().isTerminating())
return;
synchronized(owner) {
if(owner.getNumExecutors()<owner.getExecutors().size()) {
// we've got too many executors.
owner.removeExecutor(this);
try {
while(true) {
if(Hudson.getInstance().isTerminating())
return;
synchronized(owner) {
if(owner.getNumExecutors()<owner.getExecutors().size()) {
// we've got too many executors.
owner.removeExecutor(this);
return;
}
}
}
Queue.Task task;
try {
task = queue.pop();
} catch (InterruptedException e) {
continue;
}
Queue.Task task;
try {
task = queue.pop();
} catch (InterruptedException e) {
continue;
}
try {
startTime = System.currentTimeMillis();
executable = task.createExecutable();
queue.execute(executable,task);
} catch (Throwable e) {
// for some reason the executor died. this is really
// a bug in the code, but we don't want the executor to die,
// so just leave some info and go on to build other things
e.printStackTrace();
try {
startTime = System.currentTimeMillis();
executable = task.createExecutable();
queue.execute(executable,task);
} catch (Throwable e) {
// for some reason the executor died. this is really
// a bug in the code, but we don't want the executor to die,
// so just leave some info and go on to build other things
e.printStackTrace();
}
executable = null;
}
executable = null;
} catch(RuntimeException e) {
causeOfDeath = e;
throw e;
} catch (Error e) {
causeOfDeath = e;
throw e;
}
}
......@@ -77,6 +87,13 @@ public class Executor extends Thread {
return executable;
}
/**
* Same as {@link #getName()}.
*/
public String getDisplayName() {
return "Executor #"+getNumber();
}
/**
* Gets the executor number that uniquely identifies it among
* other {@link Executor}s for the same computer.
......@@ -95,6 +112,16 @@ public class Executor extends Thread {
return executable==null;
}
/**
* If this thread dies unexpectedly, obtain the cause of the failure.
*
* @return null if the death is expected death or the thread is {@link #isAlive() still alive}.
* @since 1.142
*/
public Throwable getCauseOfDeath() {
return causeOfDeath;
}
/**
* Returns the progress of the current build in the number between 0-100.
*
......
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:i="jelly:fmt">
<l:layout title="${it.name}">
<l:header />
<l:side-panel>
<l:tasks>
<l:task icon="images/24x24/up.gif" href="../.." title="Back" />
</l:tasks>
</l:side-panel>
<l:main-panel>
<j:choose>
<j:when test="${it.alive}">
<h1>
<img src="${imagesURL}/48x48/blue.gif" width="48" height="48" />
Thread is still alive
</h1>
</j:when>
<j:otherwise>
<h1>
<img src="${imagesURL}/48x48/red.gif" width="48" height="48" />
Thread has died
</h1>
<pre>${h.printThrowable(it.causeOfDeath)}</pre>
<pre>
<a href="http://hudson.gotdns.com/wiki/display/HUDSON/Dead+Executor">more info</a>
</pre>
</j:otherwise>
</j:choose>
</l:main-panel>
</l:layout>
</j:jelly>
......@@ -40,7 +40,7 @@
<j:choose>
<j:when test="${!e.alive}">
<td class="pane" width="70%">
<a href="http://hudson.gotdns.com/wiki/display/HUDSON/Dead+Executor">
<a href="${rootURL}/computers/${cloop.index}/executors/${eloop.index}/causeOfDeath">
<span class="error">Dead (!)</span>
</a>
</td>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册