I've been spelunking[1] in allegro internals for a few hours now trying to debug my ManyMouse program. I finally figured out I'm accessing a display that has been destroyed already by means of al_get_current_display returning a destroyed display. Shouldn't the thread local state (tls->current_display) be reset (zeroed) when a display is destroyed? Or set to another display if one is available?
Also, al_destroy_display does nothing to zero the memory of the display in use, so it just contains leftover garbage when you destroy it. Doesn't proper practice dictate zeroing memory when you aren't going to use it anymore? Or setting it to some kind of guard value?
I'm using Windows and D3D at the moment, so display->vt->destroy_display is currently set to d3d_destroy_display. However, free doesn't seem to be setting any guard pattern with MinGW 4.8.1 when free(display) is called (free is being called because the ALLEGRO_MEMORY_INTERFACE* mem is zero [because allegro never calls al_set_memory_interface anywhere, it is unused]).
Shouldn't the thread local state (tls->current_display) be reset (zeroed) when a display is destroyed? Or set to another display if one is available?
I think setting it to zero is what we should do.
But I already see this, so somehow you must manage to bypass that...
https://github.com/liballeg/allegro5/blob/5.1/src/win/d3d_disp.cpp#L2416
Doesn't proper practice dictate zeroing memory when you aren't going to use it anymore?
No - the memory may be reclaimed by the next memory allocation in fact and so zeroing out would not do anything. MSVC I believe has a debug setting by which it writes a pattern into free memory and does not re-use it. valgrind does the same in Linux and it's very useful.
And you can always use al_set_memory_interface to do exactly that on your own, it's why that function exists.
I think setting it to zero is what we should do.
But I already see this, so somehow you must manage to bypass that...
https://github.com/liballeg/allegro5/blob/5.1/src/win/d3d_disp.cpp#L2416
The link you gave references _al_d3d_destroy_bitmap. Perhaps you meant something else?
Doesn't proper practice dictate zeroing memory when you aren't going to use it anymore?
No - the memory may be reclaimed by the next memory allocation in fact and so zeroing out would not do anything. MSVC I believe has a debug setting by which it writes a pattern into free memory and does not re-use it. valgrind does the same in Linux and it's very useful.
And you can always use al_set_memory_interface to do exactly that on your own, it's why that function exists.
Oh, okay!! That's what that is for!
I tried looking up bit patterns used by MinGW but I couldn't find anything on Google. I thought MinGW would fill memory freed by free with some special bit pattern. I see 0xffffffffbaadfood in places (uninitialized allocated memory). How would I 'not re-use' memory? Would I have to make my own memory pool and divvy that up when my malloc is called?
The link you gave references _al_d3d_destroy_bitmap. Perhaps you meant something else?
Oh, yes, I thought the target bitmap is invalid - didn't realize we're talking about the display itself getting destroyed. So how can the current display end up pointing to a destroyed one? Only way I can see is if two threads access it at the same time - which is just not supported.
You may be right, but I'm not sure. I have two displays created on the main thread, and then all the mouse displays are created on the main display's window process thread that allegro creates in the window callback. Each mouse handles its own drawing on its window process thread that allegro created for the display in its own window process callback function. Mice are told to draw from the main displays callback process through PostMessage, which sends a message to the mouse's HWND, and drawing is taken care of by drawing from a DIB to the HWND of the mouse.
I really don't know what is causing the crash, and like I said I can only debug it on Vista. I'll try to get more info tonight, and see whether it is the backbuffer that is the bitmap that has been destroyed like you asked.