Bug - Cannot Reproduce Debug log from 10048 while autoadventuring

Magus_Prime

Well-known member
This is with r100048 using Java 6 update 29, Firefox 8, and Windows 7 32-bit.

Here's the debug log: View attachment DEBUG_20111127.txt

I was autoadventuring in Sonofa Beach during Wartime and this appeared in the gCLI:

Code:
Encounter: lobsterfrogman
Strategy: E:\software\Kol\ccs\default.ccs [default]
Round 0: Arbos wins initiative!
Run SmartStasis! (-23 profit to stasis with Saucy Salve -- low)
1/1 monsters drop goals here.
This monster is the best source of goals (1)!
Unexpected error, debug log printed.

My CCS is set to use Bale's Destroy All Monsters script. Batbrain, Smart Stasis, and Destroy All Monsters are all current. I continued the combat in the relay browser and used the "Script" button from the action bar to complete the combat and everything proceeded normally.
 
This debug log is telling me that an ArrayList object maintained in net.sourceforge.kolmafia.textui.parsetree.ForEachLoop is not being fully populated before being used. This is a potential source of bugs, unless great care is taken. Remember, ArrayLists can't be used as sparse arrays - every element before the one you wish to get or set must have something in it.
 

Veracity

Developer
Staff member
Thanks for the lecture, but the debug tells me something entirely different. And, frankly, your lecture doesn't make much sense; If an Arraylist has size X, you can get or set every index from 0 to X - 1. Every element WILL "have something in it", whether or not you set it. In particular, the "something" that is there if you don't set an element is null. Your lecture implies that fetching a null is, somehow, a problem. It is not.

java.lang.IndexOutOfBoundsException: Index: 3, Size: 6

It is getting an IndexOutOfBounds exception trying to "set" element at index 3 in an Arraylist of size 6. Java documentation for Arraylist.set says this:

Throws: IndexOutOfBoundsException - if the index is out of range (index < 0 || index >= size())

Obviously, 3 is neither < 0 nor >= 6.

So, it is trying to fetch element #3 (the old value), store a new value there, and return the old value.

Looking at the code, I see this:

Code:
		int stackPos = interpreter.iterators.size();
		interpreter.iterators.add( null );	// key
		interpreter.iterators.add( slice );	// map
		interpreter.iterators.add( keys );	// iterator

		// While there are further keys
		while ( keys.hasNext() )
		{
			// Get current key
			Value key = (Value) keys.next();
			interpreter.iterators.set( stackPos, key );
From the code and the exception, we can deduce the following:

- stackPos is the size of the ArrayList before 3 elements were added. stackPos = 3
- 3 elements were added to the end. the size of the ArrayList is now 6
- we take the exception trying to "set" the element at stackPos - index 3
- that is consistent with what the exception says: Index 3, Size 6
- the previous element at that position is explicitly set to null in the code I included.
- therefore, set() will return null. That is perfectly fine.

However, taking an IndexOutOfBounds exception for index 3 and size 6 is completely bogus.

I conclude that your Java Runtime was confused. I see nothing wrong with the code, and the exception makes no sense.

I am marking this Cannot Reproduce.
 
Top