When I run this executable it crashes with a "test.exe has encountered a problem and needs to close. We are sorry for the inconvenience." message without displaying a messagebox.
If I run it in OllyDBG it functions as expected, displaying the messagebox but it says INT3 command at ntdll.DbgBreakPoint somewhere in arrfree$'s GlobalFree call even though the array handle still seems to be valid.
if I uncomment the first messagebox it runs as expected, displaying both messageboxes, but still doesn't exit properly with or without the debugger.
include \masm32\include\masm32rt.inc
.data?
dap dd ?
.code
start:
call main
invoke ExitProcess, 0
main proc
; invoke MessageBox, 0, chr$("asdf"), chr$("asdf"), 0
mov dap, arrfile$("test.txt")
invoke MessageBox, 0, udword$(arrtotal$(dap, 1)), chr$("dap"), 0
mov eax, arrfree$(dap)
ret
main endp
end start
note: test.txt contained one line of text, when I replace it with the contents of make.bat the program exits silently rather than the "encountered a problem" message.
@box: There is indeed a problem, but knowing Hutch, he will fix it in no time. If you can't wait, try MasmBasic (http://www.masm32.com/board/index.php?topic=12460):
include \masm32\MasmBasic\MasmBasic.inc
Init
Recall "\Masm32\include\Windows.inc", L$()
MsgBox 0, L$(2), "The third string:", MB_OK
Exit
end start
@Hutch: The final call to GlobalFree in mov eax, arrfree$() fails for small files, see below. There is also always an access violation for arrfile$("I_dont_exist.txt")
include \masm32\include\masm32rt.inc
.data?
dap dd ?
.code
start:
call main
invoke ExitProcess, 0
main proc
; mov dap, arrfile$("smalltest.txt") ; GPF after "Done"
mov dap, arrfile$("\Masm32\include\Windows.inc") ; no GPF after "Done"
; mov dap, arrfile$("I_dont_exist.txt") ; GPF right here
invoke MessageBox, 0, udword$(arrtotal$(dap, 1)), chr$("dap"), 0
mov eax, arrfree$(dap)
MsgBox 0, "Done", "Hi", MB_OK
exit
main endp
end start
The help file tells you the story.
Description
Load a CRLF delimited text file and write it directly to an array.
A single line is not a CRLF delimited text file.
It works if there is a CRLF and 1 character after it thus making it a 2 line file that is CRLF delimited.
If I get time I will have a play with it but I am time poor at the moment.
It actually does what its designed to do which is load a CRLF delimited text file into an array but it in the longer haul needs so protection agains using it incorrectly.
JJ, in the arrfree proc the deallocation is,
invoke GlobalFree,[esp+4][12] ; free the pointer array
Have I missed something here ?
Here is a small test piece.
Simple text file.
test 1
test 2
test 3
test 4
Code to read it.
include \masm32\include\masm32rt.inc
.code
start:
call main
invoke ExitProcess, 0
main proc
LOCAL acnt :DWORD
LOCAL pmbr :DWORD
LOCAL hArr :DWORD
push esi
mov hArr, arrfile$("test.txt") ; load the CRLF test file
mov acnt, arrcnt$(hArr) ; count the lines
fn MessageBox,0,str$(acnt),"Count",MB_OK
mov esi, 1 ; use ESI as array index + loop counter
@@:
mov pmbr, arrget$(hArr,esi) ; get each array member by its index
fn MessageBox,0, pmbr,"Title",MB_OK
add esi, 1
cmp esi, acnt
jle @B
mov eax, arrfree$(hArr) ; free the array memory
fn MessageBox,0,str$(eax),"Return Value",MB_OK
pop esi
ret
main endp
end start
test 1
test 2
test 3
test 4
works with that code, although the process doesn't exit cleanly, and run in OllyDBG, the last messagebox fails to appear
test 1
a
test 2
test 3
test 4
fails outright with "test.exe has encountered a problem and needs to close. We are sorry for the inconvenience."
What happens for you when you try the second file?
Hutch,
The test piece fails again. I wonder if I have an old version: \masm32\m32lib\arrfile.asm dates 17.05.2008, 1337 bytes...
arralloc was writing 4 bytes past he end of the allocated array
jle @B
on line 45 of m32lib\arralloc.asm
changed to
jl @B
everything seems to work now
JJ,
Date for MASM32 distribution file is 8.9.2008.
Box,
Thanks, I will have to set the arralloc procedure up in a test piece to see what its doing. What you have suggested makes sense so I have to verify what the problem is.
Modifying the text file to the following,
test 1
1
test 2
2
test 3
3
test 4
4
Works correctly.
This is the result for the following console version of the test code.
Line count = 8
Line 1 = test 1
Line 2 = 1
Line 3 = test 2
Line 4 = 2
Line 5 = test 3
Line 6 = 3
Line 7 = test 4
Line 8 = 4
arrfree$ return value = 8
Press any key to continue ...
The console test piece.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
; Build as CONSOLE app
include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.code
start:
call main
inkey
invoke ExitProcess, 0
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
LOCAL acnt :DWORD
LOCAL pmbr :DWORD
LOCAL hArr :DWORD
push esi
mov hArr, arrfile$("test.txt") ; load the CRLF test file
mov acnt, arrcnt$(hArr) ; count the lines
print "Line count = "
print str$(acnt),13,10
mov esi, 1 ; use ESI as array index + loop counter
@@:
mov pmbr, arrget$(hArr,esi) ; get each array member by its index
print "Line "
print str$(esi)," = "
print pmbr,13,10
add esi, 1
cmp esi, acnt
jle @B
mov esi, arrfree$(hArr) ; free the array memory
print "arrfree$ return value = "
print str$(esi),13,10
pop esi
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start
Quote from: hutch-- on June 24, 2010, 10:27:30 PM
JJ,
Date for MASM32 distribution file is 8.9.2008.
My installation dates 3 August 2008, so that is probably version 9 :dazzled:
One day you could place a little file called Masm32Version.txt somewhere :bg
JJ,
After the first prototype version of the array code I rewrote the lot before the release of version 10 as I changed some very basic code in the original idea. This is the version of arralloc in MASM32 10.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.486 ; maximum processor model
.model flat, stdcall ; memory model & calling convention
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\macros\macros.asm
EXTERNDEF d_e_f_a_u_l_t__n_u_l_l_$ :DWORD
.code ; code section
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
align 16
arralloc proc mcnt:DWORD
; ----------------------------------------------------------------
; return values = handle of pointer array or 0 on allocation error
; ----------------------------------------------------------------
push esi
mov eax, mcnt ; load the member count into EAX
add eax, 1 ; correct for 1 based array
lea eax, [0+eax*4] ; multiply it by 4 for memory size
invoke GlobalAlloc,GMEM_FIXED,eax
mov esi, eax
test eax, eax ; if allocation failure return zero
jz quit
mov eax, esi
mov ecx, mcnt
mov DWORD PTR [eax], ecx ; write count to 1st member
xor edx, edx
@@:
add edx, 1 ; write adress of null string to all members
mov [eax+edx*4], OFFSET d_e_f_a_u_l_t__n_u_l_l_$
cmp edx, ecx
jle @B
mov eax, esi ; return pointer array handle
quit:
pop esi
ret
arralloc endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end
Quote from: hutch-- on June 24, 2010, 10:45:29 PM
JJ,
After the first prototype version of the array code I rewrote the lot before the release of version 10 as I changed some very basic code in the original idea. This is the version of arralloc in MASM32 10.
Hutch,
At home I have version 9, at work version 10, and that is the latest one indeed. The exception happens in a non-predictable way, but in any case the little modification by box seems to fix the problem. The exception for non-existant files persists, though.
Best,
Jochen