Uploaded image for project: 'Undertow'
  1. Undertow
  2. UNDERTOW-1953

AbstractFramedChannel.toString() not thread safe

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: Minor Minor
    • None
    • 2.2.7.Final
    • Core
    • None
    • Hide

      Interleave calls to WebSocketChannel.toString() with lots of activity on the same socket across multiple threads.

      Show
      Interleave calls to WebSocketChannel.toString() with lots of activity on the same socket across multiple threads.
    • undefined

      We saw the following exception thrown in our application under heavy load:

      java.util.ConcurrentModificationException
      {{ at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:966)}}
      {{ at java.util.LinkedList$ListItr.next(LinkedList.java:888)}}
      {{ at java.util.AbstractCollection.toString(AbstractCollection.java:461)}}
      {{ at io.undertow.server.protocol.framed.AbstractFramedChannel.toString(AbstractFramedChannel.java:1111)}}

      This is the referenced source code: https://github.com/undertow-io/undertow/blob/e6e7fb78a1762bf584ef4324dac149860157ef3a/core/src/main/java/io/undertow/server/protocol/framed/AbstractFramedChannel.java#L1111

      We believe the issue is that pendingFrames is a java.util.LinkedList, and that while pendingFrames.toString() is running in one thread, pendingFrames is being modified in another, and the java.util.ConcurrentModificationException is thrown.

      As a java.util.ArrayDeque, heldFrames appears to be susceptible to the same race condition, but we haven't observed that yet in our application.

      toString() is getting called by our code that converts WebSocketChannels to strings and logs them. We were able to work around the issue by boxing the WebSocketChannel objects logged by our application in a class with a safe toString().

      We think it would be best if toString() was thread safe, which seems most easily accomplished by removing the calls to pendingFrames.toString() and heldFrames.toString(). Alternatively, pendingFrames and heldFrames could be converted to data structures more tolerant of concurrent access, but such a change would be considerably more invasive.

      If a patch toward either of these (or some other) end is desirable, please let me know and I'll be happy to work on one.

      Thank you for taking the time to review this issue.

       

              rhn-cservice-bbaranow Bartosz Baranowski
              alan-14 Alan Dipert (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated:
                Resolved: