-
Notifications
You must be signed in to change notification settings - Fork 42
Closed
Milestone
Description
The basic logic of ThreadLeakControl.checkThreadLeaks(...) is...
HashSet<Thread> threads = getThreads(suiteFilters);
if (threads.isEmpty()) return
// optional wait and retry if ThreadLeakLinker is configured
// Take one more snapshot, this time including stack traces (costly).
HashMap<Thread,StackTraceElement[]> withTraces = getThreadsWithTraces(suiteFilters);
if (withTraces.isEmpty()) return
// Build up failure message (include stack traces of leaked threads).
StringBuilder message = new StringBuilder(threads.size() + " thread" +
(threads.size() == 1 ? "" : "s") +
" leaked from " +
scope + " scope at " + description + ": ");
message.append(formatThreadStacks(withTraces));
..but that final message includes a mix of information from both threads and withTraces, even though the information in threads is stale, and may include threads that aren't in withTraces (ie: because the Thread properly died in between the method calls)
This can lead to messages like this, where the number of threads doesn't make sense...
2> SEVERE: 2 threads leaked from SUITE scope at org.apache.solr.util.OrderedExecutorTest:
2> 1) Thread[id=3510, name=testLockWhenQueueIsFull_control-2506-thread-1, state=TERMINATED, group={null group}]
2> at (empty stack)
It seems like the messages could always be internally consistent if checkThreadLeaks(...) stopped using threads variable once the withTraces variable was populated -- just use withtraces.keySet() in it's place .(or do something like threads = withtraces.keySet(); right after the withTraces.isEmpty() check)
Metadata
Metadata
Assignees
Labels
No labels