WinBatch® Technical Support Forum

All Things WinBatch => WinBatch => Topic started by: MacroLabs on September 19, 2013, 10:14:14 AM

Title: WinBatch Array Redimension / Binary Buffer Bug
Post by: MacroLabs on September 19, 2013, 10:14:14 AM
When the following code is run, data inside some of the binary buffers becomes corrupted.

Quote
ARR=ARRDIMENSION(1)

BUFFER=BINARYALLOC(480000)

#DEFINEFUNCTION ARRAYREDIM_WORKAROUND(ARR,DIM1,DIM2,DIM3,DIM4,DIM5)
   ARRAYREDIM(ARR,DIM1,DIM2,DIM3,DIM4,DIM5)
#ENDFUNCTION

#DEFINEFUNCTION TEST(ARR)
   INDEX=ARRINFO(ARR,1)
   ARRAYREDIM(ARR,INDEX+1,-1,-1,-1,-1)
;   ARRAYREDIM_WORKAROUND(ARR,INDEX+1,-1,-1,-1,-1)
   BIN=BINARYALLOC(32)
   BINARYPOKESTR(BIN,0,"THIS IS A TEST STRING.")
   ARR[INDEX]=BIN
#ENDFUNCTION

TEST(ARR)
TEST(ARR)
TEST(ARR)
TEST(ARR)

#DEFINEFUNCTION PRINT_R(ARR)
   TEXT=""
   FOR X=0 TO ARRINFO(ARR,1)-1
      IF ISDEFINED(ARR[X]) THEN TEXT=TEXT:X:" => [":BINARYPEEKSTR(ARR[X],0,32):"]":@CRLF
   NEXT
   RETURN TEXT
#ENDFUNCTION

MESSAGE("",PRINT_R(ARR))

However, if the ArrayRedim() function is placed inside of another function and called via the other function, the data corruption does not occur.
Title: Re: WinBatch Array Redimension / Binary Buffer Bug
Post by: Deana on September 19, 2013, 11:36:54 AM
I am unable to reproduce any problem on Windows 7 using WinBatch 2031C. Could you please provide the version of WinBatch and the version of the Windows Platform where you see the problem.

Also DebugTrace output might be helpful.

Code (winbatch) Select
DEBUGTRACE(@ON,"TRACE.TXT")
ARR=ARRDIMENSION(1)

BUFFER=BINARYALLOC(480000)

#DEFINEFUNCTION ARRAYREDIM_WORKAROUND(ARR,DIM1,DIM2,DIM3,DIM4,DIM5)
   DEBUGTRACE(22)
   ARRAYREDIM(ARR,DIM1,DIM2,DIM3,DIM4,DIM5)
   RETURN ARR
#ENDFUNCTION

#DEFINEFUNCTION TEST(ARR)
   DEBUGTRACE(22)
   INDEX=ARRINFO(ARR,1)
   ARRAYREDIM(ARR,INDEX+1,-1,-1,-1,-1)
;   ARRAYREDIM_WORKAROUND(ARR,INDEX+1,-1,-1,-1,-1)
   BIN=BINARYALLOC(32)
   BINARYPOKESTR(BIN,0,"THIS IS A TEST STRING.")
   ARR[INDEX]=BIN
   RETURN ARR
#ENDFUNCTION

TEST(ARR)
TEST(ARR)
TEST(ARR)
TEST(ARR)

#DEFINEFUNCTION PRINT_R(ARR)
   TEXT=""
   FOR X=0 TO ARRINFO(ARR,1)-1
      IF ISDEFINED(ARR[X]) THEN TEXT=TEXT:X:" => [":BINARYPEEKSTR(ARR[X],0,32):"]":@CRLF
   NEXT
   RETURN TEXT
#ENDFUNCTION

RESULTS = PRINT_R(ARR)
MESSAGE("", RESULTS)
Title: Re: WinBatch Array Redimension / Binary Buffer Bug
Post by: kdmoyers on September 19, 2013, 12:57:17 PM
Quote from: Deana on September 19, 2013, 11:36:54 AM
I am unable to reproduce any problem on Windows 7 using WinBatch 2031C

me too: no bug on Windows 7 using WinBatch 2031C

also, maybe post screen shot of what your results are.

-Kirby
Title: Re: WinBatch Array Redimension / Binary Buffer Bug
Post by: td on September 19, 2013, 01:23:23 PM
I wasn't able to reproduce the problem directly either but was able to find a significant issue via other means.  The problem has nothing directly to do with binary buffers and is the result of how the array reference change is being propagated during the return from the UDF call. 

I would not count on the proposed workaround consistently working either. For now you should not use the ArrayRedim, ArrayRemove, or ArrayInsert functions inside UDF/S's on arrays passed as parameters to the UDF/S.

One safe workaround would be to define and access the array as a global pointer.
Code (winbatch) Select

PtrGlobalDefine(arr)

#DEFINEsubroutine TEST()
   parr = ptrGlobal(arr)

   INDEX=ArrInfo(*parr,1)
   ArrayRedim(*parr,INDEX+1,-1,-1,-1,-1)
   BIN=BinaryAlloc(32)
   BinaryPokestr(BIN,0,"THIS IS A TEST STRING.")
   *parr[INDEX]=BIN
#ENDFUNCTION


We really appreciate users taking the time to  report problems like this and we should have it fixed in the next release.
Title: Re: WinBatch Array Redimension / Binary Buffer Bug
Post by: MacroLabs on September 19, 2013, 02:57:51 PM
Okay, thanks td!

Just for documentation purposes, attached is a screenshot of the output that I was receiving.  (It varied every time I ran the program)
Title: Re: WinBatch Array Redimension / Binary Buffer Bug
Post by: MacroLabs on September 19, 2013, 03:17:00 PM
Would this be a safe workaround?  I pass an array reference to the function and then dereference it inside the function.

Code (winbatch) Select

ARR=ArrDimension(0)

#DefineFunction TEST(ARR)
   INDEX=ArrInfo(*ARR,1)
   ArrayRedim(*ARR,INDEX+1,-1,-1,-1,-1)
   BIN=BinaryAlloc(32)
   BinaryPokeStr(BIN,0,"THIS IS A TEST STRING.")
   *ARR[INDEX]=BIN
#EndFunction

TEST(&ARR)
Title: Re: WinBatch Array Redimension / Binary Buffer Bug
Post by: td on September 20, 2013, 07:10:57 AM
Excellent.  Yes, that does work around the problem and is a cleaner solution than using a global pointer. 
Title: Re: WinBatch Array Redimension / Binary Buffer Bug
Post by: kdmoyers on September 20, 2013, 09:19:46 AM
Quote from: td on September 20, 2013, 07:10:57 AM
Excellent.  Yes, that does works around the problem and is a cleaner solution than using a global pointer.
(laugh) Heck, most of the time I do it that way anyway, forgetting that arrays are supposed to pass by reference.  That might be why I've never noticed the bug.

Nice catch Macrolabs !!
Title: Re: WinBatch Array Redimension / Binary Buffer Bug
Post by: td on September 20, 2013, 10:20:44 AM
Well, it also may be the case that you haven't seen it because the stars have to be aligned just right to produce it in the first place.  It took over three years for a user to report a problem with the function.