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-

new topic     » topic index » view message » categorize

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-

new topic     » goto parent     » topic index » view message » categorize

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>

>
>

---

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu