WinBatch Array Redimension / Binary Buffer Bug

Started by MacroLabs, September 19, 2013, 10:14:14 AM

Previous topic - Next topic

MacroLabs

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.

Deana

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)
Deana F.
Technical Support
Wilson WindowWare Inc.

kdmoyers

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
The mind is everything; What you think, you become.

td

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.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

MacroLabs

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)

MacroLabs

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)

td

Excellent.  Yes, that does work around the problem and is a cleaner solution than using a global pointer. 
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

kdmoyers

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 !!
The mind is everything; What you think, you become.

td

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.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade