New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ChannelBufferInputStream throws IndexOutOfBoundsException #474
Comments
This bug is present in Netty 3.5.2 and 3.5.3, maybe also in other versions. Perhaps this bug is related to Issue #445? |
@mvysny would it be possible to share a unit test to reproduce ? |
I'm very sorry but I can't reproduce it on a regular basis. Perhaps this issue is reproducible only if TCP packets arrive with a certain size? |
The problem seems to be caused by some kind of inconsistency between the value returned by CompositeChannelBuffer.readableBytes() and internal CompositeChannelBuffer state (the indices[] array). I tried to run the server in debug mode, to check for these inconsistencies, but so far it works flawlessly in debug mode. |
@mvysny let me know if you find out more.. |
Hi, I ma also seeing this issue pretty consistently. Do we have any further information on this issue? Let me know if you want me to collect any specific data. -Yogesh |
@yogeshvedpathak some way to reproduce it would be very helpful. |
@mvysny @yogeshvedpathak I suspect there is a bug in the componentId(..) method of CompositeChannelBuffer.. |
@normanmaurer I thought that CompositeChannelBuffer is a culprit. But then the code is very similar to 3.2.7. The difference is most exceptions have message 3.5.3. Then I started thinking that it may be FrameDecoder. This class has substantial changes to cumulating buffer. Is it possible that copy buffer in that code is not setting read index properly? I am trying to setup a test environment where I can reproduce it and set a breakpoint. |
Looks like i the issue is indeed in CompositeChannelBuffer. I made following change to CompositeChannelBuffer .componentId() 663c663
|
Also note that, I see the issue when i write around 100MB data on the connection. |
@yogeshvedpathak let me see if I can write a unit test to reproduce and then verify the fix |
@yogeshvedpathak I was not able to reproduce it with a unit test yet. Can you explain why you thing this change is needed ? |
Here is the snapshot for CompositeChannelBuffer: index = 294565 (componentId's parameter) lastComponentId = 240 If i make that if condition <= then then lastComponentId is returned instead of throwing exception. I hope this helps. |
Looking from the snapshot, the capacity of the buffer is |
@yogeshvedpathak did you see @trustin 's comment ? |
@normanmaurer yes I did. And it make sense. Actually i did run into IOOBE during another test because of that change. I don't have new update. I will spend some more time on this on Monday. |
@yogeshvedpathak ok let me know once you have more details |
So i was not able to reproduce it in the unit test. However the problem is very consistant on actual server. Also our server disconnects the client if there is no IO for few seconds. So debugging this issue with the breakpoint set is hard. I added some logging to the CompositeChannelBuffer. I see that this happens right after setComponenet is called with indices size 730 and components size 729. and call to componentId fails when accessing index 1052764. So logically we are trying to access the index which i not set? In general I don't understand if it is okay to have no synchronization in ChannelBuffer code. Can you suggest anything to investigate this further? |
@normanmaurer after adding some more loggin I was able to figure out exact condition when this exception is thrown. This happens if CompositeChannelBuffer.readBytes(ByteBuffer) is called with zero buffer being passed is zero length. I am not sure what is/should be contract of this method. For not i fixed my code to not call readBytes with empty buffer. Let me know what you think. |
@yogeshvedpathak I tried to reproduce it was a test case but was not able todo.. Could you submit one ? |
@yogeshvedpathak is correct. However, it is more than just a zero length byte array being passed to readBytes(). The issue requires that the CompositeChannelBuffer readerIndex be sitting at the exact end of the entire buffer and at that point an attempt is made to read an empty byte array. The fix here is simple. At the top of all the getBytes methods an if-statement causes the method to exit. Here's an example for getBytes(int index, byte[] dst, int dstIndex, int length) on line 230: public void getBytes(int index, byte[] dst, int dstIndex, int length) {
if (length == 0) {
return;
}
int componentId = componentId(index);
... The unit test will look something like this (pseudo code):
|
Thanks, Will take care today ;) Sent from my iPhone. Excuse any typos.... Am 22.09.2012 um 16:04 schrieb voidmain notifications@github.com:
|
…e readerIndex is at the last position and an empty array is passed to read to. See #474
@voidmain @yogeshvedpathak thanks again for all the details.. I just pushed a fix which will be part of 3.5.8.Final. Please let me know if you still have any issues... |
…e readerIndex is at the last position and an empty array is passed to read to. See #474
Hi guys, thank you for an excellent library!
During some very specific conditions, I can always trigger the following error. Can you please
take a quick look at it, perhaps you can spot the problem very easily. If not, I will try to provide sample data to trigger the issue, but it will take some time as it is not easy
to simulate these very specific conditions.
java.lang.IndexOutOfBoundsException: Invalid index: 174351, maximum: 14
at org.jboss.netty.buffer.CompositeChannelBuffer.componentId(CompositeChannelBuffer.java:684)
at org.jboss.netty.buffer.CompositeChannelBuffer.getBytes(CompositeChannelBuffer.java:231)
at org.jboss.netty.buffer.AbstractChannelBuffer.readBytes(AbstractChannelBuffer.java:339)
at org.jboss.netty.handler.codec.replay.ReplayingDecoderBuffer.readBytes(ReplayingDecoderBuffer.java:318)
at org.jboss.netty.buffer.ChannelBufferInputStream.readFully(ChannelBufferInputStream.java:166)
at org.jboss.netty.buffer.ChannelBufferInputStream.readFully(ChannelBufferInputStream.java:161)
at com.innovatrics.jobcluster.common.messages.DataUtils.readBytes(DataUtils.java:46)
at com.innovatrics.jobcluster.common.messages.MessageFrame.(MessageFrame.java:35)
at com.innovatrics.jobcluster.server.connector.tcp.MessagingNettyServer$MessageFrameDecoder.decode(MessagingNettyServer.java:62)
at com.innovatrics.jobcluster.server.connector.tcp.MessagingNettyServer$MessageFrameDecoder.decode(MessagingNettyServer.java:58)
at org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:502)
at org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:487)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:91)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:385)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:256)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
The text was updated successfully, but these errors were encountered: