News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

A memory bug

Started by TouEnMasm, May 16, 2013, 05:56:12 PM

Previous topic - Next topic

TouEnMasm


This one is a bug not easy to find.
Run the exe,select a file and right clic to get the context menu.
The exe will just quit.
Responsible is the dynamic change of stack size who show no problem.
If someone could find some enlightment it would be very usefull.
There is differents problems with various number of stack pages required.
Windbg give this result when he find one:
Quote
(d54.5d0): Access violation - code c0000005 (first chance)
MSVCR80!_setusermatherr+0x4b5:
78131637 8500            test    dword ptr [eax],eax  ds:0023:00125000=????????
Fa is a musical note to play with CL

sinsi

I get no crash or anything, just a context menu. Selecting cancel takes me to the exe's window.
Under windbg I also get no crash, but every right click loads a bunch of dlls over and over.
In the middle is this error:
(c6c.1744): Unknown exception - code 000006ba (first chance)

jj2007

That's a known problem of GetOpenFileName. Nothing serious, though, it seems the dll handles it internally.

TouEnMasm


I have windows XP 3 and the "nothing serious" is just a fast exitprocess without saving anything.
The state of the msvrc80.dll seem responsible of that.
I have tried to load it,to view it's version,this failed with a prompt it is "loaded incorrectly",but I had no bug after the prompt.
Fa is a musical note to play with CL

dedndave

the silent exit may be caused by a stack allocation that is beyond the current commit
you could probe the stack down, say 4 kb or 8 kb - even 32 kb, then call it to verify
        ASSUME  FS:Nothing

        mov     eax,esp
        mov     edx,esp
        sub     eax,32768

@@:     push    edx
        mov     esp,fs:[8]
        cmp     eax,esp
        jb      @B

        mov     esp,edx

        ASSUME  FS:ERROR

TouEnMasm


I don't see really what do this test.
For me , if the stack commit is not > stack reserve,all is good.
Fa is a musical note to play with CL

jj2007

Quote from: ToutEnMasm on May 16, 2013, 10:34:15 PM
I have windows XP 3 and the "nothing serious" is just a fast exitprocess...

Me too Windows XP SP3, and it works fine. Maybe it doesn't like French Windows ::)

KeepingRealBusy

What usually gets me in trouble is that I allocate all of memory with Virtual Alloc - and leave none to load the debugger. If any exception occurs, then you get an instant termination with no messages, no way to find out what went wrong.

Dave.

qWord

Unfortunately I don't speak French, thus I'm not able to read the comments nor the identifiers, but the problem is caused by "AgrandirPile", which calls VirtualAlloc for memory that belongs to the stack. After I NOP'ed out the "call AgrandirPile", the executable work perfect (Win7, x64) - you might simply let Windows manage the stack.
MREAL macros - when you need floating point arithmetic while assembling!

TouEnMasm


Quote
After I NOP'ed out the "call AgrandirPile", the executable work perfect (Win7, x64) - you might simply let Windows manage the stack.
It is what i have done,but i want to know if there is a way to avoid the problem.
I have verify the function step by step and don't see only one reason for what openfinename is on trouble.

I have simplify it a little.



AgrandirPile PROC uses esi edi ebx Nbpages:DWORD ,Affichage:DWORD
Local  adrRegion:DWORD,Pagedemande,tailletotale
Local  TailleRegion:DWORD,TailleMemTemp,plusregion,NewbaseAdress
Local  Tampon[100]:BYTE
Local  PageAlloue:DWORD,flAllocationType,flProtect
LOCAL  Tempmemorybasic:MEMORY_BASIC_INFORMATION,sysinfo:SYSTEM_INFO
Local  retour:DWORD
ZEROLOCALES retour
invoke GetSystemInfo,addr sysinfo ;SYSTEM_INFO
;first read ,get the BaseAdress of the pointer on memory
invoke VirtualQuery,esp,addr Tempmemorybasic,sizeof Tempmemorybasic
PuPo   TailleMemTemp,Tempmemorybasic.RegionSize
lecturezone:
;loop decreasing the BaseAdress by one page until he failed
;the region size increase by one page
mov edx,Tempmemorybasic.BaseAddress
sub edx,sysinfo.dwPageSize
invoke VirtualQuery,edx,addr Tempmemorybasic,sizeof Tempmemorybasic
mov edx,TailleMemTemp
add edx,sysinfo.dwPageSize
mov eax,Tempmemorybasic.RegionSize
.if eax == edx   ;same region
;keep the good values
PuPo   TailleMemTemp,Tempmemorybasic.RegionSize
PuPo   NewbaseAdress,Tempmemorybasic.BaseAddress
jmp lecturezone
.endif
;------ fill the Tempmemorybasic with the good values --------
invoke VirtualQuery,NewbaseAdress,addr Tempmemorybasic,sizeof Tempmemorybasic


;-------- get the properties of the region for Vitualalloc
;flAllocationType,flProtect
;invoke VirtualAlloc,Tempmemorybasic.BaseAddress,edx,\
; MEM_COMMIT or MEM_TOP_DOWN ,PAGE_READWRITE
;mov eax,Tempmemorybasic.type1  ;type1=MEM_IMAGE,MEM_MAPPED,MEM_PRIVATE
;mov flAllocationType,eax
mov eax,Tempmemorybasic.State  ;State=MEM_COMMIT,MEM_FREE,MEM_RESERVE
mov flAllocationType,eax
;-----------------------------------
mov ecx,Tempmemorybasic.AllocationProtect ;PAGE_EXECUTE ..
mov flProtect,ecx
;
;-------------- memory is read -------------------------------------------------------
;find the base adress and the size for the new region
mov eax,TailleMemTemp ;Tempmemorybasic.RegionSize
mov ecx,sysinfo.dwPageSize
xor edx,edx
div ecx
mov PageAlloue,eax
.if eax < Nbpages
;tout va bien
jmp @F    ;continuer
.else
mov retour,0
jmp FindeAgrandirPile
.endif

@@:
;we can do it
mov eax,Nbpages
mov edx,0
mov ecx,sysinfo.dwPageSize
mul ecx
mov tailletotale,eax ;total size of new region
mov eax,Nbpages
sub eax,PageAlloue ;pages already allocated
mov Pagedemande,eax ;number of pages to increase
mov edx,0
mov ecx,sysinfo.dwPageSize
mul ecx
mov plusregion,eax
;adresse a alloué
mov edx,Tempmemorybasic.BaseAddress
sub edx,plusregion
;on tient une adresse
invoke VirtualAlloc,edx,tailletotale,\
flAllocationType,flProtect
; MEM_COMMIT or MEM_TOP_DOWN ,PAGE_READWRITE


.if eax == 0
mov retour,0
jmp FindeAgrandirPile
.else
invoke LecturePile,0

.endif


FindeAgrandirPile:
         mov eax,retour
         ret
AgrandirPile endp

Fa is a musical note to play with CL

jj2007

Why AgrandirPile? As qWord wrote already, Windows manages the stack quite well. If it's not sufficient, use a stackprobe macro...

TouEnMasm


If by a stackprobe macro (unknown in this forum),you want to say "use the linker" to solve this,it is what i have done.
The problem stay without a soluce.I have read that another system use another dialog API to open files.Must be the soluce.
Thanks at all.
Fa is a musical note to play with CL

dedndave

you can use the code in reply #4 to probe the stack
i used 32768 bytes, but you can probe it down to whatever depth you like

the last line of code, MOV ESP,EDX sets ESP to the original value
but, i would normally use MOV ESP,EAX to adjust ESP to the desired depth

qWord

#13
I don't understand why the stack size must be changed, but at least increasing it is easy (see above).
For your code I see the problem that it removes the guarded page blow the current stack, which is used by system to detected if an application needs more stack-memory. Also, the question is how to inform the system that you have changed the stack size - I've doubts that the TIB entry is sufficient.

EDIT: for stack probe I would use this one: I would use dave's approach too
mov edx,esp
and edx,NOT (4096-1)
sub edx,4096
xor ecx,ecx
.while ecx < 10 ; 10 = number of pages
or BYTE ptr [edx],0
sub edx,4096
add ecx,1
.endw
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

that code assumes what ? 4 kb pages ?
i thought they were 2 kb - lol
no matter

Yves uses GetSystemInfo to determine the page size
and - i think it is a constant over all versions of windows, to date

but, in my probe code, i use the value at FS:[8]
whatever the page size is, it will be correct, as it uses the current stack commit as the next probe address   :P
that also ensures a minumum number of probe loop passes, i.e. faster