Skip to content

msgs from ThreadLeakControl.checkThreadLeaks can be inconsistent due to mismatched use of thread data #303

@hossman

Description

@hossman

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions