Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - PJägare

Pages: [1]
1
Window / Access violation in RenderWindow::GetEvent
« on: August 18, 2011, 04:42:23 pm »
All right, I understand why DestroyWindow and so forth should not always be called. However, I think you missed my point regarding SetWindowLongPtr.

Quote from: "Laurent"
SetWindowLongPtr assigns custom data to a window. So there's no point assigning something to a window that is going to be destroyed.


In particular, on line 83 of WindowImplWin32.cpp, the WindowImplWin32 being created is assigned as custom data to the provided window handle:

Code: [Select]
WindowImplWin32::WindowImplWin32(WindowHandle handle) :
    //...
{
    if (myHandle)
    {
        //...
        SetWindowLongPtr(myHandle, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); // line 83
        myCallback = SetWindowLongPtr(myHandle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&WindowImplWin32::GlobalOnEvent));
    }
}


or, in the case of non-external windows (which is what we have), on line 815:
Code: [Select]
   // Associate handle and Window instance when the creation message is received
    if (message == WM_CREATE)
    {
        // Get WindowImplWin32 instance (it was passed as the last argument of CreateWindow)
        LONG_PTR window = (LONG_PTR)reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams;

        // Set as the "user data" parameter of the window
        SetWindowLongPtr(handle, GWLP_USERDATA, window); // line 815
    }

But in the destructor this association between the window handle and the WindowImplWin32 object is not broken. The window may be about to be destroyed, but it has not been destroyed yet, and if the window is sent a message before it is destroyed, it will fetch that pointer to the now deallocated WindowImplWin32, and access it. And this does in fact happen.

By adding something like
Code: [Select]
if (myHandle)
    SetWindowLongPtr(myHandle, GWLP_USERDATA, NULL);

to the destructor, this would be protected against. In fact, you have an if-guard on line 822 for that very purpose.

2
Window / Access violation in RenderWindow::GetEvent
« on: August 18, 2011, 03:25:10 pm »
The problem remains in SFML2, but using static linking we've been able to gather more information.

The access violation occurs in Window/Win32/WindowImplWin32.cpp, on line 827 (debugger screenshot).

The immediate cause of the problem appears to be that the call GetWindowLongPtr(handle, GWLP_USERDATA) on line 819 returns a pointer to an object that has been deallocated.
On reviewing the code, the WindowImplWin32 destructor seems odd.
Code: [Select]
WindowImplWin32::~WindowImplWin32()
{
    // Destroy the custom icon, if any
    if (myIcon)
        DestroyIcon(myIcon);

    if (!myCallback)
    {
        // Destroy the window
        if (myHandle)
            DestroyWindow(myHandle);

        // Decrement the window count
        WindowCount--;

        // Unregister window class if we were the last window
        if (WindowCount == 0)
        {
            if (HasUnicodeSupport())
            {
                UnregisterClassW(ClassNameW, GetModuleHandle(NULL));
            }
            else
            {
                UnregisterClassA(ClassNameA, GetModuleHandle(NULL));
            }
        }
    }
    else
    {
        // The window is external : remove the hook on its message callback
        SetWindowLongPtr(myHandle, GWLP_WNDPROC, myCallback);
    }
}


Admittedly we're not fully up to speed on the details of window creation and desctruction, but shouldn't the part in the if (!myCallback)-statement always happen, so that DestroyWindow is called?

Alternately, if that is correct, should perhaps SetWindowLongPtr(myHandle, GWLP_USERDATA, 0) be used to deregister the object being destroyed?

3
Window / Access violation in RenderWindow::GetEvent
« on: August 14, 2011, 07:32:41 am »
Unfortunately no. The error does not occur in a clearly defined part of the code that could be isolated. In fact, the event that causes the window to close and the call to GetEvent that crashes are not even in the same iteration of the main loop.

What I was hoping for was some insight into what GetEvent does that could access invalid memory. For example, does it access anything created outside of SFML that might have been incorrectly deallocated? Or do windows use some shared resource that must be specially managed? Or anything else that comes to mind?

4
Window / Access violation in RenderWindow::GetEvent
« on: August 13, 2011, 07:26:05 pm »
Hello.

We are developing an application that under some circumstances uses several windows. We have encountered a problem where closing one window causes an access violation in the GetEvent method of a different window.
The problem is timing based or otherwise semirandom in that it appears only occasionally when running on my computer, but often or always on my partner's computer.
The application has several threads, but all window creation, destruction and event handling is on the main thread.

Any idea what could be causing this?

Pages: [1]