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=????????
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)
That's a known problem of GetOpenFileName. (http://masm32.com/board/index.php?topic=1656.msg16859#msg16859) Nothing serious, though, it seems the dll handles it internally.
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.
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
I don't see really what do this test.
For me , if the stack commit is not > stack reserve,all is good.
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 ::)
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.
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.
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
Why AgrandirPile? As qWord wrote already, Windows manages the stack quite well. If it's not sufficient, use a stackprobe macro...
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.
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
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
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
Quote from: dedndave on May 17, 2013, 11:46:50 PM
that code assumes what ? 4 kb pages ?
i thought they were 2 kb - lol
please show me a x86 processor that supports 2 kb pages.
you're right - they are 4 kb
as i said, you don't have to know what the page size is if you use my code :P
Quote from: dedndave on May 18, 2013, 12:03:14 AM
as i said, you don't have to know what the page size is if you use my code :P
indeed, your solution is better because it is page-size-independent :icon14:
a little demo
you can watch the bottom-of-stack (TIB.StackLimit) value change at each loop pass
actually, i think that's the top-of-stack, but the wiki page calls it the bottom :P
Perhaps an explain on how it work,the FS[8] change,How ?.
And where did you find this ?
the operating system maintains the value in the thread information block
as you use more stack space, it commits additional pages, as required
i didn't find it - i wrote it
i was using some other code previously - it used GetSystemInfo to find the page size
but, i wanted a faster method for inline probing to create buffers for an EnumReg function i was writing
so, i did a little research and found that the TIB had the stack limit value
it dawned on me that the page size isn't needed if you use the current stack limit value :P
how ever much the OS commits (even if it were more than 1 page), you probe the current limit until you get what you want
Ok , your method is an answer to the memory problem with openfilename.
There is no problem after changing the stack size with the right clic.
:t
I find just an error,the stack is full when you exit,modify it like below:
bytes_required = 0A000h
mov keepesp,esp ;keep the actual esp in data
ASSUME FS:Nothing
mov eax,esp
sub eax,bytes_required
and al,-16 ;let's use 16-align for demo purposes
@@: push eax
;call ShowStackBottom ;for demo purposes only
mov esp,fs:[8]
cmp eax,esp
jb @B
mov esp,keepesp ;old position
ASSUME FS:ERROR
Quote from: ToutEnMasm on May 18, 2013, 02:23:01 AMOk , your method is an answer to the memory problem with openfilename.
There is no problem after changing the stack size with the right clic.
The simples method is to leave the stack as it is. I'm really curios what you want to archive...
Quote
The simples method is to leave the stack as it is. I'm really curios what you want to archive...
The increase of the stack size allow fast load (see microsoft) .
Sample,when you load mutiples files an put them in a richedit,the work is faster with a modify stack.The result is visible.
if you go back to reply #4, you will see that the original ESP is stored in EDX, then restored when done probing
you only need to change the 32768 to 0A000h in that code
Quote from: ToutEnMasm on May 18, 2013, 03:00:19 AMThe increase of the stack size allow fast load (see microsoft)
where can I read about that (link)?
Quote from: ToutEnMasm on May 18, 2013, 03:00:19 AMSample,when you load mutiples files an put them in a richedit,the work is faster with a modify stack.The result is visible.
I am very curious to see a comparison. Seriously - I'd love to speed up my RichMasm editor (http://www.masmforum.com/board/index.php?topic=9044).
Quote
I am very curious to see a comparison. Seriously - I'd love to speed up my RichMasm editor.
Simple,made test on your IDE changing the stack size with the linker,you will have an answer.
Here a full explain of the method and a proc who give the amount of desired memory in bytes rounded to the next upper page.
comment µ
NT_TIB STRUCT DEFALIGNMASM ;winnt.sdk
ExceptionList DWORD ?
StackBase DWORD ?
StackLimit DWORD ?
SubSystemTib DWORD ?
IF DEFINED(_MSC_EXTENSIONS)
union
FiberData DWORD ?
Version DWORD ?
ENDS
ELSE
FiberData DWORD ?
ENDIF
ArbitraryUserPointer DWORD ?
Self DWORD ?
NT_TIB ENDS
µ
;nbytes,desired sizeof stack,rounded to the next upper page
;################################################################
SystemIncreaseStack PROC nbytes:DWORD
Local keepesp:DWORD
mov ecx,0
mov keepesp,esp
ASSUME FS:Nothing
stackloop:
mov edx,FS:[ecx].NT_TIB.StackLimit
mov eax,FS:[ecx].NT_TIB.StackBase
sub eax,edx ;allocated stack
.if eax < nbytes ;let's the system made a round in page
mov esp,FS:[ecx].NT_TIB.StackLimit
push eax ;write outside this limit and let the system increase the stack
jmp stackloop
.endif
ASSUME FS:ERROR
mov esp,keepesp
;eax new size
ret
SystemIncreaseStack endp
Quote from: ToutEnMasm on May 18, 2013, 03:19:19 PM
Quote
I am very curious to see a comparison. Seriously - I'd love to speed up my RichMasm editor.
Simple,made test on your IDE changing the stack size with the linker,you will have an answer.
Good proposal. So here is the answer:
Loading a 13,000 lines source into a RichEdit control:
- stack 12 MB: 1.0 seconds
- stack 0.5 MB: 0.75 seconds
Your turn 8)
I can't see any significant difference either. Running on my Windows XP P3 system, loading the current MASM32 windows.inc 10 times, whether I use the default stack size, or /STACK:10000000,10000000, I get ~1720ms.
;==============================================================================
; Build as a console app.
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
IDC_RE equ 100
;==============================================================================
;----------------------------------------------------------------------
; This is a general-purpose control definition macro that adds support
; for controls of any type to the MASM32 In-Memory Dialogs. For this
; macro the control class is specified as a quoted string, instead of
; being hard coded.
;----------------------------------------------------------------------
DlgControl MACRO quoted_caption,quoted_class,dstyle,tx,ty,wd,ht,ctlID
align_4 edi
mov DWORD PTR [edi+0], WS_VISIBLE or WS_CHILD or dstyle
mov WORD PTR [edi+8], tx
mov WORD PTR [edi+10], ty
mov WORD PTR [edi+12], wd
mov WORD PTR [edi+14], ht
mov WORD PTR [edi+16], ctlID
add edi, 18
ustring quoted_class
ustring quoted_caption
;-------------------------------------------
; Advance edi past the creation data array.
;-------------------------------------------
add edi, 2
ENDM
;==============================================================================
.data
hInst HMODULE 0
hwndRE HWND 0
hFile HANDLE 0
flag dd 0
editstream EDITSTREAM <1,,EditStreamCallback>
filename db "\masm32\include\windows.inc",0
.code
;==============================================================================
EditStreamCallback proc dwCookie:DWORD, pbBuff:DWORD, cb:DWORD, pcb:DWORD
invoke ReadFile, hFile, pbBuff, cb, pcb, NULL
xor eax, eax
ret
EditStreamCallback endp
;==============================================================================
DlgProc proc hwndDlg:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL rc:RECT
SWITCH uMsg
CASE WM_INITDIALOG
invoke CreateFile, ADDR filename, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, NULL, NULL
mov hFile, eax
invoke GetDlgItem, hwndDlg, IDC_RE
mov hwndRE, eax
invoke SendMessage, hwndRE, EM_EXLIMITTEXT, 1000000*10, 0
CASE WM_SYSCOMMAND
.IF flag == 0
inc flag
invoke GetTickCount
push eax
REPEAT 10
invoke SendMessage, hwndRE,
EM_STREAMIN,
SF_TEXT,
ADDR editstream
invoke SetFilePointer, hFile, 0, NULL, FILE_BEGIN
ENDM
invoke GetTickCount
pop edx
sub eax, edx
printf("%dms\n", eax)
.ENDIF
CASE WM_SIZE
invoke GetClientRect, hwndDlg, ADDR rc
invoke MoveWindow, hwndRE, 0, 0, rc.right, rc.bottom, TRUE
CASE WM_COMMAND
SWITCH wParam
Case IDCANCEL
invoke CloseHandle,hFile
invoke EndDialog, hwndDlg, NULL
ENDSW
CASE WM_CLOSE
invoke CloseHandle,hFile
invoke EndDialog, hwndDlg, NULL
EndSw
return 0
DlgProc endp
;==============================================================================
start:
;==============================================================================
invoke LoadLibrary, chr$("RICHED20.DLL")
invoke GetModuleHandle, NULL
mov hInst, eax
Dialog "Click title bar to start test", \
"Courier New",8, \
WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
1, \
0,0,200,150, \
1024
DlgControl 0, \
"RichEdit20A", \
WS_VSCROLL or \
WS_HSCROLL or \
ES_SUNKEN or \
ES_MULTILINE or \
ES_AUTOVSCROLL or \
ES_AUTOHSCROLL or \
ES_NOHIDESEL or \
ES_WANTRETURN, \
0,0,0,0,IDC_RE
CallModalDialog hInst, 0, DlgProc, NULL
exit
;==============================================================================
end start
I didn't think to test the effect of the RE control styles, and I am apparently testing a Rich Edit 3.0 control.
Quote from: MichaelW on May 18, 2013, 06:10:11 PM
I can't see any significant difference either. Running on my Windows XP P3 system...
With Celeron M, XP SP3:
- 400k stack: 407 ms
- 8M stack: 407 ms
In fact, my own tests tell the same story (the 0.75 secs were an outlier :biggrin:).
It is a nice habit to
measure things instead of just declaring "truths" as if Moses himself had been giving a helping hand ;-)
Quote
It is a nice habit to measure things instead of just declaring "truths" as if Moses himself had been giving a helping hand ;-)
I have just declared truth in one particular case,not on all.
Everybody can test it if it is usefull or not in his case.
There is an image you regularly get in medieval movies in times of plague where lines of pilgrims walk along the streets chanting and self flagelating and every time I have read this thread the image comes back to me. In 32 bit PE executables that stack is set by the linker and is part of the OS design, it is not a dynamic resizable stack. Now while there are various reasons why you vary these two parameters, upwards for recursion or downwards if a particular application must have the smallest memory footprint possible, trying to dynamically size the stack looks and sounds like those folks of long ago who deliberately harm themselves.
there are times when the amount of stack space required is not known until runtime
i don't see any harm in probing the stack to increase the space available by TIB.StackLimit
QuoteIn 32 bit PE executables that stack is set by the linker and
is part of the OS design, it is not a dynamic resizable stack.
i would say it's dynamic, as the OS continually balances the need for stack space with the need for heap space
Make this simple test ,put in the WM_DESTROY message and you will see the amount of stack memory reserved dynamically by the system .
On my XP SP3 it start at 3000h bytes,for my IDE it end at 16000h bytes
Take care with 64 bits there is a NT_TIB64:
NT_TIB64 STRUCT DEFALIGNMASM
ExceptionList QWORD ?
StackBase QWORD ?
StackLimit QWORD ?
SubSystemTib QWORD ?
IF DEFINED(_MSC_EXTENSIONS)
union
FiberData QWORD ?
Version DWORD ?
ENDS
ELSE
FiberData QWORD ?
ENDIF
ArbitraryUserPointer QWORD ?
Self QWORD ?
NT_TIB64 ENDS
WM_DESTROY
invoke StackSize
mov edx,eax
invoke BaseN,edx,16,addr ZoneMessagesErreurs
invoke MessageBox,NULL,ADDR ZoneMessagesErreurs,SADR("Taille Pile"),MB_OK
;################################################################
StackSize PROC
ASSUME FS:Nothing
mov ecx,0
mov edx,FS:[ecx].NT_TIB.StackLimit ;FS:[8]
mov eax,FS:[ecx].NT_TIB.StackBase ;FS:[4]
sub eax,edx ;allocated stack
ASSUME FS:ERROR
ret
StackSize endp
Found where is the bug:
windbg give me
Quote;MSVCR80!_chkstk+27 [crt\src\intel\chkstk.asm @ 99] 78131637 8500 test dword ptr [eax],eax
The "chkstk.asm " is in the c++express crt source code.
Viewing it:
Quote
; Find next lower page and probe
cs20:
sub eax, _PAGESIZE_ ; decrease by PAGESIZE
test dword ptr [eax],eax ; probe page. <<< comment is clear
jmp short cs10
What i have done is just read the size of the stack at the end,using the openfile fialog.Size stack needed by the dialog in pages is 13 pages.
Now using the dynamic allocation of stack with virtualloc i choose 16 pages to allocate and no more bug with a right clic on a file.
This show that virtualloc uninstall the guard page interrupt (_XCPT_GUARD_PAGE_VIOLATION).
If someone know how to reinstall it,put it here. (Found Virtual Protect PAGEGUARD)