Menu

#69 Access violation in AxWindow.dll in AxWindow_DESTROY

open
5
2008-01-31
2007-03-19
No

This is a very unusual bug and is very hard to trace what is happening. Unfortunately, there is a lot of effort required to simplify the sample script into a pure Win32::GUI script and so I can only provide a Win32::GUI::XMLBuilder file.

You will need the following modules (latest) installed.

Win32::GUI
Win32::GUI::AxWindow
Win32::GUI::XMLBuilder
Win32::TieRegistry
Win32

To replicate the crash you must run: -

perl.exe buildfile.pl crash.wgx

Now when you terminate the application using the close button or ALT+F4 an access violation happens. Here is the call stack: -

AxWindow.dll!ATL::AtlUnadvise(IUnknown * pUnkCP=0x0006d9f8, const _GUID & iid={...}, unsigned long dw=1) Line 49 + 0x17 bytes
AxWindow.dll!CEventMap::UnAdvise(IUnknown * spunk=0x0006d9f8) Line 765
AxWindow.dll!CContainer::Clean() Line 1364
AxWindow.dll!CContainer::~CContainer() Line 1333
AxWindow.dll!CContainer::`scalar deleting destructor'() + 0xf bytes
AxWindow.dll!XS_Win32__GUI__AxWindow_DESTROY(interpreter * my_perl=0x00233cc4, cv * cv=0x021c999c) Line 2680 + 0x1c bytes
perl58.dll!Perl_pp_entersub(interpreter * my_perl=0x00233cc4) Line 2817 + 0x12 bytes
perl58.dll!S_call_body(interpreter * my_perl=0x00233cc4, const op * myop=0x0140fcbc, char is_eval=0) Line 2807 + 0x9 bytes
perl58.dll!Perl_call_sv(interpreter * my_perl=0x00233cc4, sv * sv=0x021c999c, long flags=150) Line 2738 + 0xf bytes
perl58.dll!Perl_sv_clear(interpreter * my_perl=0x00233cc4, sv * sv=0x02399108) Line 4562 + 0x12 bytes
perl58.dll!Perl_sv_free(interpreter * my_perl=0x00233cc4, sv * sv=0x02399108) Line 4770 + 0xd bytes
perl58.dll!do_clean_objs(interpreter * my_perl=0x00233cc4, sv * sv=0x02398f94) Line 416 + 0xd bytes
perl58.dll!S_visit(interpreter * my_perl=0x00233cc4, void (interpreter *, sv *)* f=0x280f6330, unsigned long flags=524288, unsigned long mask=524288) Line 360 + 0xb bytes
perl58.dll!Perl_sv_clean_objs(interpreter * my_perl=0x00233cc4) Line 460 + 0x18 bytes
perl58.dll!perl_destruct(interpreter * my_perl=0x00233cc4) Line 848 + 0x9 bytes
perl58.dll!RunPerl(int argc=3, char * * argv=0x00252e48, char * * env=0x00253158) Line 252 + 0x9 bytes
perl.exe!main(int argc=3, char * * argv=0x00252e48, char * * env=0x00253158) Line 23 + 0x12 bytes
perl.exe!__tmainCRTStartup() Line 586 + 0x17 bytes

The access violation occurs in AtlUnadvise when trying to access the m_spDispatch member of the container object. This member appears to be deleted earlier. An ATL trace shows this happening at a Win32::GUI DestroyWindow phase.

What makes the bug very strange is that by removing any single Win32::GUI element (from the XML file) or even some eval-ed code will prevent the access violation.

Possibly something to do with stack size or desktop memory?

Discussion

  • Anonymous

    Anonymous - 2007-03-19

    Sample WGX file

     
  • Anonymous

    Anonymous - 2007-03-19

    WGX bootstrap script

     
  • Anonymous

    Anonymous - 2007-03-19

    Logged In: YES
    user_id=910559
    Originator: YES

    File Added: buildfile.pl

     
  • Anonymous

    Anonymous - 2007-03-19

    Logged In: YES
    user_id=910559
    Originator: YES

    Another interesting note. By adding an AxWindow object earlier to the Win32::GUI tree this can also remove the Access Violation.

     
  • Anonymous

    Anonymous - 2007-03-19

    Logged In: YES
    user_id=910559
    Originator: YES

    Another interesting note. By adding an AxWindow object earlier to the Win32::GUI tree this can also remove the Access Violation.

     
  • Robert May

    Robert May - 2007-07-16

    Logged In: YES
    user_id=674651
    Originator: NO

    I'm afraid that I'm really not in a position to help here. I know my way around the WIn32 API pretty well, but I'm out of my depth with ATL, and especially with the guts of AxWindow.

    From the stack trace it looks to me like you're in perl global destruction (perl_destruct), and in this phase the ref counts on perl objects get reduced until the destructors get called. There's no particular order here, and so if the object representing a window that is a parent (or higher ancestor) of the AxWindow class gets destroyed first, then DestoryWindow() will be called on it, and all it's children, resulting in the AxWindow being destroyed, even though a perl object referencing it still exists. The the AxWindow's perl object gets it's reference count reduced to zero, resulting in it's destructor being called, which results in us trying to destroy things a second time.

    If you are in a position where you can compile Win32::GUI::AxWindow, then download the source and try removing the comments from the printf's in CContainer::Clean, and see if it's getting called twice. If this is the case, then I'd hazard a guess that m_spDispath should be set to NULL after the calls to Unadvise() and Release(), so that they don't get called the second time through. If you're not in a position to compile it yourself, let me know and I'll have a go at building one for you.

    Regards,
    Rob.

     
  • Robert May

    Robert May - 2007-07-16
    • assigned_to: nobody --> robertemay
     
  • Robert May

    Robert May - 2008-01-31
    • labels: --> Win32::GUI::AxWindow
     

Log in to post a comment.