1. Subclassing crash
Hi all
Please, take a look at this:
--=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D
function ControlProc (atom hWnd,atom wMsg,atom wParam,atom lParam)
integer c , ret
c=3D1
ret=3Dc_func(CallWindowProc,{SubControl, hWnd, wMsg, wParam, lParam})
if c then end if
return ret
end function
SubControl=3Dcall_back(routine_id("ControlProc"))
--=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
It's the hook procedure for a subclassed control.
On execution, i get a machine level crash with a message like:
"The instruction at 0040bd67 referenced memory at fffffff8
The memory could not be read from
Click on OK to terminate the application"
If i comment line "if c then end if", works ok.
It seems like var c has been destroyed.
If i declare c outside the function, works ok, also.
Why does it happens?
Thanks
-George-
2. Re: Subclassing crash
On Fri, 24 Jan 2003 16:07:33 -0500, Matt Lewis wrote:
>It looks like you simply pass the callback to ControlProc, where you =
should
>be passing the pointer to the default procedure for that control.
Sorry, I was wrong in previous post.
SubControl=3Dc_func(SetWindowLong,{ hControl, GWL_WNDPROC,
call_back(routine_id("ControlProc"))})
Check it out
--=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
without warning
include msgbox.e
constant
user32=3Dopen_dll("user32.dll"),
CallWindowProc=3Ddefine_c_func(user32,"CallWindowProcA",{C_ULONG,C_ULONG,=
C_ULONG,C_ULONG,C_ULONG},C_INT),
CreateWindowEx=3Ddefine_c_func(user32,"CreateWindowExA",{C_ULONG,C_ULONG,=
C_ULONG,C_ULONG,C_ULONG,C_ULONG,C_ULONG,C_ULONG,C_ULONG,C_ULONG,C_ULONG,C=
_ULONG},C_INT),
SetWindowLong=3Ddefine_c_func(user32,"SetWindowLongA",{C_ULONG,C_ULONG,C_=
ULONG},C_INT),
PostQuitMessage=3Ddefine_c_func(user32,"PostQuitMessage",{C_ULONG},C_INT)=
,
DefWindowProc=3Ddefine_c_func(user32,"DefWindowProcA",{C_ULONG,C_ULONG,C_=
ULONG,C_ULONG},C_INT),
LoadIcon=3Ddefine_c_func(user32,"LoadIconA",{C_ULONG,C_ULONG},C_INT),
LoadCursor=3Ddefine_c_func(user32,"LoadCursorA",{C_ULONG,C_ULONG},C_INT),
RegisterClass=3Ddefine_c_func(user32,"RegisterClassA",{C_ULONG},C_INT),
ShowWindow=3Ddefine_c_func(user32,"ShowWindow",{C_ULONG,C_ULONG},C_INT),
UpdateWindow=3Ddefine_c_func(user32,"UpdateWindow",{C_ULONG},C_INT),
GetMessage=3Ddefine_c_func(user32,"GetMessageA",{C_ULONG,C_ULONG,C_ULONG,=
C_ULONG},C_INT),
TranslateMessage=3Ddefine_c_func(user32,"TranslateMessage",{C_ULONG},C_IN=
T),
DispatchMessage=3Ddefine_c_func(user32,"DispatchMessageA",{C_ULONG},C_INT=
),
WS_CHILD=3D#40000000,
WS_VISIBLE=3D#10000000,
GWL_WNDPROC=3D#FFFFFFFC,
WM_CREATE=3D#1,
WM_DESTROY=3D#2,
sizeofMSG=3D28,
sizeofWNDCLASS=3D40,
WNDCLASS_style=3D0,
CS_HREDRAW=3D#2,
CS_VREDRAW=3D#1,
WNDCLASS_lpfnWndProc=3D4,
WNDCLASS_cbClsExtra=3D8,
WNDCLASS_cbWndExtra=3D12,
WNDCLASS_hInstance=3D16,
WNDCLASS_hbrBackground=3D28,
COLOR_WINDOW=3D#5,
WNDCLASS_lpszMenuName=3D32,
WNDCLASS_lpszClassName=3D36,
IDI_WINLOGO=3D#7F05,
WNDCLASS_hIcon=3D20,
IDC_ARROW=3D#7F00,
WNDCLASS_hCursor=3D24,
WS_OVERLAPPEDWINDOW=3D#CF0000,
WS_MAXIMIZEBOX=3D#10000,
SW_SHOWNORMAL=3D#1
object ret
atom hButton
atom SubControl
function ControlButtProc(atom hWnd,atom wMsg,atom wParam,atom lParam)
integer c
c=3D1
ret=3Dc_func(CallWindowProc,{ SubControl, hWnd, wMsg, wParam,
lParam})
if c then end if ------> COMMENT/UNCOMMENT THIS LINE=20
return ret
end function
function Button(atom hParent,sequence Name,integer x,integer y,integer
w,integer h,integer id)
atom szName
atom szClassName
atom hButt
szName=3Dallocate_string(Name)
szClassName=3Dallocate_string("BUTTON")
hButt=3Dc_func(CreateWindowEx,{ NULL, szClassName, szName,
WS_CHILD + WS_VISIBLE,
x, y, w, h, hParent, id, instance(), 0 })
free(szName)
free(szClassName)
SubControl=3Dc_func(SetWindowLong,{ hButt, GWL_WNDPROC,
call_back(routine_id("ControlButtProc"))})
return hButt
end function
function WndProc(atom hWnd,atom wMsg,atom wParam,atom lParam)
if wMsg =3D WM_CREATE then
hButton=3DButton( hWnd,"My Button", 25, 25, 80, 25, 10)
return 0
elsif wMsg =3D WM_DESTROY then
ret=3Dc_func(PostQuitMessage,{NULL})
return 0=20
=20
end if
return c_func(DefWindowProc,{hWnd,wMsg,wParam,lParam})
end function
procedure WinMain()
atom wc
atom msg
atom hMainWnd
atom szDisplayName
atom szClassName
msg=3Dallocate(sizeofMSG)
szDisplayName=3Dallocate_string("My Win")
szClassName=3Dallocate_string("My_Win_Class")
wc=3Dallocate(sizeofWNDCLASS)
poke4(wc+WNDCLASS_style,CS_HREDRAW+CS_VREDRAW)
poke4(wc+WNDCLASS_lpfnWndProc,call_back(routine_id("WndProc")))
poke4(wc+WNDCLASS_cbClsExtra,NULL)
poke4(wc+WNDCLASS_cbWndExtra,NULL)
poke4(wc+WNDCLASS_hInstance,instance())
poke4(wc+WNDCLASS_hbrBackground,COLOR_WINDOW)
poke4(wc+WNDCLASS_lpszMenuName,NULL)
poke4(wc+WNDCLASS_lpszClassName,szClassName)
ret=3Dc_func(LoadIcon,{NULL,IDI_WINLOGO})
poke4(wc+WNDCLASS_hIcon,ret)
ret=3Dc_func(LoadCursor,{NULL,IDC_ARROW})
poke4(wc+WNDCLASS_hCursor,ret)
ret=3Dc_func(RegisterClass,{wc})
free(wc)
hMainWnd=3Dc_func(CreateWindowEx,{NULL,
szClassName,
szDisplayName,
xor_bits(WS_OVERLAPPEDWINDOW,WS_MAXIMIZEBOX),
0,0,340,200,
NULL,NULL,
instance(),NULL})
=20
free(szDisplayName)
free(szClassName)
ret=3Dc_func(ShowWindow,{hMainWnd,SW_SHOWNORMAL})
ret=3Dc_func(UpdateWindow,{hMainWnd})
while c_func(GetMessage,{msg, NULL, 0, 0}) do
ret=3Dc_func(TranslateMessage,{msg})
ret=3Dc_func(DispatchMessage,{msg})
end while
free(msg)
end procedure
WinMain()
--=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-George-
3. Re: Subclassing crash
Hi Matt,
Thanx for the exception lib. i'm gonna create my own which gives more
detailed feed back. Anyway thanx for the idea. I won't hack/steal ur code as
some pple think. i'll just code my own based on ur idea.
----------------
Jordah
----- Original Message -----
From: "Matthew Lewis" <matthewwalkerlewis at YAHOO.COM>
To: "EUforum" <EUforum at topica.com>
Subject: RE: Subclassing crash
>
>
> I get the error, too. I've written a little include that catches
> exceptions, and then does a divide by zero, so I can get a nice trace back
> (see the code after the trace). Here are the important lines from ex.err:
>
> C:\Documents and Settings\lewismat\My Documents\Eu\EDSGUI\exceptions.ew:45
> in function exception()
> attempt to divide by 0
> ex = 456376
> record = 0
> context = 456608
> params = 2
> i = 2
>
> ^^^ call-back from Windows
>
> ... called from george.exw:62 in function ControlButtProc()
> hWnd = <no value>
> wMsg = <no value>
> wParam = <no value>
> lParam = <no value>
> c = <no value>
>
> ^^^ call-back from Windows
>
> Traced lines leading up to the failure:
>
> george.exw:60 c=1
> george.exw:62 ret=c_func(CallWindowProc,{ SubControl, hWnd, wMsg,
> wParam, lParam})
> george.exw:60 c=1
> george.exw:62 ret=c_func(CallWindowProc,{ SubControl, hWnd, wMsg,
> wParam, lParam})
> george.exw:64 if c then end if ------> COMMENT/UNCOMMENT
> THIS LINE
> george.exw:66 return ret
> george.exw:60 c=1
> george.exw:62 ret=c_func(CallWindowProc,{ SubControl, hWnd, wMsg,
> wParam, lParam})
> george.exw:64 if c then end if ------> COMMENT/UNCOMMENT
> THIS LINE
> george.exw:66 return ret
> george.exw:64 if c then end if ------> COMMENT/UNCOMMENT
> THIS LINE
>
>
> Somehow, Eu thinks that c has no value. If you assign the value to c
after
> the call to CallWindowProc, it runs fine. Rob, this definitely smells
like
> a bug in the interpreter...
>
> Matt Lewis
>
>
> -- exceptions.ew
>
> include dll.e
> constant
> k32 = open_dll("kernel32.dll"),
> xSetUnhandledExceptionFilter = define_c_func( k32,
> "SetUnhandledExceptionFilter",
> {C_POINTER}, C_POINTER )
> without trace
> include get.e
> global atom the_ptr, traceback
> traceback = 1
> the_ptr = 0
>
> constant
> EXCEPTION_EXECUTE_HANDLER = 1,
> EXCEPTION_CONTINUE_EXECUTION = 0,
> EXCEPTION_CONTINUE_SEARCH = -1
>
> function exception( atom ex )
> atom record, context, params
>
> record = peek4u( ex )
> puts(1,"Exception:\n")
> while record do
>
>
printf(1,"Code:\t%08x\nFlags:\t%08x\nnext:\t%08x\nAddr:\t%08x\nParams:\t%d\n
> ",
> peek4u({record,6}))
> params = peek4u(record+16)
> for i = 1 to params do
> printf(1,"param[%d]:\t%08x\n", {i,peek4u( record + 16 +
i*4 )})
> end for
> record = peek4u(record+8)
> end while
>
> context = peek4u( ex + 4 )
> ? peek({context,10})
> if the_ptr and 0 then
> for i = 1 to 200 do
> printf(1,"%04d:\t%08x\n",{i-1,peek4u(the_ptr + (i-1)*4)})
> end for
> ?peek({peek4u(the_ptr+53*4),10})
> printf(1,"%s\n", {peek({peek4u(the_ptr+53*4),10})})
> end if
> puts(1,"Press any key to continue\n")
> if wait_key() then end if
> if traceback then ? 1/0 end if
> return EXCEPTION_EXECUTE_HANDLER
> end function
>
>
> if c_func( xSetUnhandledExceptionFilter,
> {call_back(routine_id("exception"))}) then end if
> -- end exceptions.ew
>
>
> > From: George Papadopoulos [mailto:georgp at otenet.gr]
> > Check it out
> >
> > --======================================================
> >
> > without warning
> >
> > include msgbox.e
> >
> > constant
> > user32=open_dll("user32.dll"),
> >
> > CallWindowProc=define_c_func(user32,"CallWindowProcA",{C_ULONG
> ,C_ULONG,C_ULONG,C_ULONG,C_ULONG},C_INT),
> > CreateWindowEx=define_c_func(user32,"CreateWindowExA",{C_ULONG
> ,C_ULONG,C_ULONG,C_ULONG,C_ULONG,C_ULONG,C_ULONG,>
> C_ULONG,C_ULONG,C_ULONG,C_ULONG,C_ULONG},C_INT),
> > SetWindowLong=define_c_func(user32,"SetWindowLongA",{C_ULONG,C
> _ULONG,C_ULONG},C_INT),
> > PostQuitMessage=define_c_func(user32,"PostQuitMessage",{C_ULON
> > G},C_INT),
> > DefWindowProc=define_c_func(user32,"DefWindowProcA",{C_ULONG,C
> _ULONG,C_ULONG,C_ULONG},C_INT),
> > LoadIcon=define_c_func(user32,"LoadIconA",{C_ULONG,C_ULONG},C_INT),
> > LoadCursor=define_c_func(user32,"LoadCursorA",{C_ULONG,C_ULONG
> > },C_INT),
> > RegisterClass=define_c_func(user32,"RegisterClassA",{C_ULONG},C_INT),
> > ShowWindow=define_c_func(user32,"ShowWindow",{C_ULONG,C_ULONG},C_INT),
> > UpdateWindow=define_c_func(user32,"UpdateWindow",{C_ULONG},C_INT),
> > GetMessage=define_c_func(user32,"GetMessageA",{C_ULONG,C_ULONG
> > ,C_ULONG,C_ULONG},C_INT),
> > TranslateMessage=define_c_func(user32,"TranslateMessage",{C_UL
> > ONG},C_INT),
> > DispatchMessage=define_c_func(user32,"DispatchMessageA",{C_ULO
> > NG},C_INT),
> >
> > WS_CHILD=#40000000,
> > WS_VISIBLE=#10000000,
> > GWL_WNDPROC=#FFFFFFFC,
> > WM_CREATE=#1,
> > WM_DESTROY=#2,
> > sizeofMSG=28,
> > sizeofWNDCLASS=40,
> > WNDCLASS_style=0,
> > CS_HREDRAW=#2,
> > CS_VREDRAW=#1,
> > WNDCLASS_lpfnWndProc=4,
> > WNDCLASS_cbClsExtra=8,
> > WNDCLASS_cbWndExtra=12,
> > WNDCLASS_hInstance=16,
> > WNDCLASS_hbrBackground=28,
> > COLOR_WINDOW=#5,
> > WNDCLASS_lpszMenuName=32,
> > WNDCLASS_lpszClassName=36,
> > IDI_WINLOGO=#7F05,
> > WNDCLASS_hIcon=20,
> > IDC_ARROW=#7F00,
> > WNDCLASS_hCursor=24,
> > WS_OVERLAPPEDWINDOW=#CF0000,
> > WS_MAXIMIZEBOX=#10000,
> > SW_SHOWNORMAL=#1
> >
> >
> > object ret
> > atom hButton
> > atom SubControl
> >
> >
> > function ControlButtProc(atom hWnd,atom wMsg,atom wParam,atom lParam)
> >
> > integer c
> >
> > c=1
<snip>
>
>
---
4. Re: Subclassing crash
Matthew Lewis writes:
> Somehow, Eu thinks that c has no value.
> If you assign the value to c after
> the call to CallWindowProc, it runs fine.
> Rob, this definitely smells like
> a bug in the interpreter...
If you can make a small runnable program for me,
I'll take a look at it. 2.4 can catch the exception.
I don't really follow what it's supposed to be doing,
but maybe the c_func call caused some corruption,
that led to the variable c having the magic bit-pattern
NOVALUE as it's value.
Regards,
Rob Craig
Rapid Deployment Software
http://www.RapidEuphoria.com
5. Re: Subclassing crash
Matt Lewis writes
(regarding a bug reported by George Papadopoulos):
> Somehow, Eu thinks that c has no value.
> If you assign the value to c after
> the call to CallWindowProc, it runs fine.
> Rob, this definitely smells like a bug in the interpreter...
Thanks Matt for sending me an easy example of this.
I've found and fixed the bug.
It has to do with a call-back routine calling itself indirectly
thus causing unexpected recursion to happen.
The fix was easy and will also reduce the
overhead on most call-backs by 10% or so.
The fix will be in 2.4 alpha (still about 10 days away).
Regards,
Rob Craig
Rapid Deployment Software
http://www.RapidEuphoria.com