Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Crash in d3d_shutdown

This thread is locked; no one can reply to it. rss feed Print
Crash in d3d_shutdown
Edgar Reynaldo
Member #8,592
May 2007
avatar

I've been receiving an intermittent crash in d3d_shutdown when my program exits. Why would it crash on the line _al_d3d->Release() unless _al_d3d was an invalid pointer? My window sets up fine and I don't believe I am double freeing anything.

I'm using MinGW 4.5.0 on Vista with latest Allegro from Git.

#SelectExpand
1 2Program received signal SIGSEGV, Segmentation fault. 30x693df8b7 in d3d_shutdown () at C:\mingw\LIBS\A5GIT\allegro\src\win\d3d_disp.cpp:2604 42604 _al_d3d->Release(); 5(gdb) p _al_d3d 6$1 = (LPDIRECT3D9) 0x25b07e0 7(gdb) bt 8#0 0x693df8b7 in d3d_shutdown () at C:\mingw\LIBS\A5GIT\allegro\src\win\d3d_disp.cpp:2604 9#1 0x693cfa88 in win_shutdown () at C:\mingw\LIBS\A5GIT\allegro\src\win\wsystem.c:197 10#2 0x6936fcd1 in shutdown_system_driver () at C:\mingw\LIBS\A5GIT\allegro\src\system.c:77 11#3 0x69363fe1 in _al_run_exit_funcs () at C:\mingw\LIBS\A5GIT\allegro\src\exitfunc.c:92 12#4 0x69370015 in al_uninstall_system () at C:\mingw\LIBS\A5GIT\allegro\src\system.c:302 13#5 0x6ab41086 in __dll_exit () from c:\ctwoplus\progcode\eagle5gui\cbbuild\bin\eagle_a5d.dll 14#6 0x6ab4110a in DllMainCRTStartup@12 () from c:\ctwoplus\progcode\eagle5gui\cbbuild\bin\eagle_a5d.dll 15#7 0x778aded4 in ntdll!RtlDefaultNpAcl () from C:\Windows\system32\ntdll.dll 16#8 0x7789a959 in ntdll!RtlExtendMemoryBlockLookaside () from C:\Windows\system32\ntdll.dll 17#9 0x7789a8db in ntdll!RtlExtendMemoryBlockLookaside () from C:\Windows\system32\ntdll.dll 18#10 0x77553d77 in KERNEL32!ExitThread () from C:\Windows\system32\kernel32.dll 19#11 0x00000000 in ?? () 20(gdb)

Any ideas why this is happening?

I think it has something to do with my reworked timer class but I don't know what. I've got a thread that runs TimerProcess and communicates with an Allegro5Timer through means of an ALLEGRO_EVENT_QUEUE. States between the TimerProcess and the Allegro5Timer are synchronized using the allegro event queues. When the timer sends a message to the timer process, it waits for a matching return message so that the states are synchronized. I don't destroy anything twice, I'm sure, and I destroy every ALLEGRO_THREAD, ALLEGRO_TIMER and ALLEGRO_EVENT_QUEUE that I create.

Here's the code for Allegro5Timer.cpp if it helps.

#SelectExpand
1 2 3 4#include "Eagle/backends/Allegro5/Allegro5EventHandler.hpp" 5#include "Eagle/backends/Allegro5/Allegro5Timer.hpp" 6#include "Eagle/backends/Allegro5/Allegro5Threads.hpp" 7 8 9 10 11enum EAGLE_TIMER_MESSAGE_TYPE { 12 EAGLE_MESSAGE_CREATE_TIMER = 0, 13 EAGLE_MESSAGE_START_TIMER = 1, 14 EAGLE_MESSAGE_STOP_TIMER = 2, 15 EAGLE_MESSAGE_CLOSE_TIMER = 3 16}; 17 18 19 20void* TimerProcess(EagleThread* ethread , void* etimer) { 21 EagleTimer* eagle_timer = (EagleTimer*)etimer; 22 Allegro5Timer* eagle_a5_timer = dynamic_cast<Allegro5Timer*>(eagle_timer); 23 EAGLE_ASSERT(eagle_a5_timer); 24 25 ALLEGRO_TIMER* timer = eagle_a5_timer->AllegroTimer(); 26 ALLEGRO_EVENT_QUEUE* queue = eagle_a5_timer->AllegroEventQueue(); 27 ALLEGRO_EVENT_SOURCE* event_source = eagle_a5_timer->AllegroEventSource(); 28 29 EAGLE_ASSERT(timer); 30 EAGLE_ASSERT(queue); 31 EAGLE_ASSERT(event_source); 32 33 int counter = 0; 34 bool close = false; 35 while (!ethread->ShouldStop() && !close) { 36 ALLEGRO_EVENT ev; 37 al_wait_for_event(queue , &ev); 38 OutputLog() << "Event " << ev.type << std::endl; 39 if (ev.type == ALLEGRO_EVENT_TIMER && ev.timer.source == (ALLEGRO_TIMER*)eagle_a5_timer->Source()) { 40 ++counter; 41 eagle_a5_timer->Tick(al_get_time()); 42 } 43 else if (ev.type == EAGLE_EVENT_USER_START) { 44 switch (ev.user.data1) { 45 case EAGLE_MESSAGE_CREATE_TIMER : 46 OutputLog() << "EAGLE_MESSAGE_CREATE_TIMER received." << std::endl; 47 break; 48 case EAGLE_MESSAGE_START_TIMER : 49 al_start_timer(timer); 50 OutputLog() << "EAGLE_MESSAGE_START_TIMER received." << std::endl; 51 break; 52 case EAGLE_MESSAGE_STOP_TIMER : 53 al_stop_timer(timer); 54 OutputLog() << "EAGLE_MESSAGE_STOP_TIMER received." << std::endl; 55 break; 56 case EAGLE_MESSAGE_CLOSE_TIMER : 57 close = true; 58 OutputLog() << "EAGLE_MESSAGE_CLOSE_TIMER received." << std::endl; 59 break; 60 default : EAGLE_ASSERT(0); 61 break; 62 } 63 al_emit_user_event(event_source , &ev , 0);// bounce message back to synchronize states 64 } 65 } 66 return (void*)counter; 67} 68 69 70 71void Allegro5Timer::SendTimerProcessMessage(int message) { 72 ALLEGRO_EVENT ev; 73 ev.type = EAGLE_EVENT_USER_START; 74 ev.user.data1 = message; 75 al_emit_user_event(&timer_event_source , &ev , NULL); 76} 77 78 79 80Allegro5Timer::Allegro5Timer() : 81 EagleTimer(), 82 timer(0), 83 timer_queue(0), 84 process_queue(0), 85/// queue_lock(0), 86 timer_event_source(), 87 process_event_source(), 88 ethread(0) 89{ 90 al_init_user_event_source(&timer_event_source); 91 al_init_user_event_source(&process_event_source); 92// queue_lock = al_create_mutex(); 93} 94 95 96 97Allegro5Timer::~Allegro5Timer() { 98 Destroy(); 99// al_destroy_mutex(queue_lock); 100// queue_lock = 0; 101} 102 103 104 105bool Allegro5Timer::Create(double seconds_per_tick) { 106 EAGLE_ASSERT(seconds_per_tick > 0.0); 107 108 Destroy(); 109 110 OutputLog() << "Allegro5Timer::Create this=" << this << std::endl; 111 112 timer = al_create_timer(seconds_per_tick); 113 timer_queue = al_create_event_queue(); 114 process_queue = al_create_event_queue(); 115 116 ethread = new Allegro5Thread(); 117 118 EAGLE_ASSERT(timer); 119 EAGLE_ASSERT(timer_queue); 120 EAGLE_ASSERT(process_queue); 121 122 if (timer && timer_queue && process_queue) { 123 spt = seconds_per_tick; 124 previous_ticks = current_ticks = al_get_timer_count(timer); 125 al_register_event_source(process_queue , al_get_timer_event_source(timer)); 126 al_register_event_source(process_queue , &timer_event_source); 127 al_register_event_source(timer_queue , &process_event_source); 128 /// MUST create TimerProcess thread AFTER registering event sources or it will wait forever 129 ethread->Create(TimerProcess , this); 130 131 // wait for thread to synchronize 132 133 if (ethread->Valid()) { 134 ethread->Start(); 135 136 // send out create message to thread process 137 ALLEGRO_EVENT ev; 138 ev.type = EAGLE_EVENT_USER_START; 139 ev.user.data1 = EAGLE_MESSAGE_CREATE_TIMER; 140 al_emit_user_event(&timer_event_source , &ev , 0); 141 142 // wait for return message 143 do { 144 al_wait_for_event(timer_queue , &ev); 145 } while (!((ev.type == EAGLE_EVENT_USER_START) && (ev.user.data1 == EAGLE_MESSAGE_CREATE_TIMER))); 146 147 return true; 148 } 149 } 150 151 if (!timer_queue) { 152 OutputLog() << "Allegro5Timer::Create - Could not create an Allegro 5 Timer - Couldn't create timer_queue." << std::endl; 153 } 154 if (!process_queue) { 155 OutputLog() << "Allegro5Timer::Create - Could not create an Allegro 5 Timer - Couldn't create process_queue." << std::endl; 156 } 157 if (!timer) { 158 OutputLog() << "Allegro5Timer::Create - Could not create an Allegro 5 Timer - Couldn't create an ALLEGRO_TIMER." << std::endl; 159 } 160 if (!ethread->Valid()) { 161 OutputLog() << "Allegro5Timer::Create - ethread is not valid." << std::endl; 162 } 163 164 // The queue or the timer failed to be created 165 Destroy(); 166 return false; 167} 168 169 170 171void Allegro5Timer::Destroy() { 172 OutputLog() << "Allegro5Timer::Destroy this=" << this << std::endl; 173 174 Close(); 175 176 if (timer_queue) { 177 al_unregister_event_source(timer_queue , &process_event_source); 178 al_unregister_event_source(timer_queue , al_get_timer_event_source(timer)); 179 al_destroy_event_queue(timer_queue); 180 timer_queue = 0; 181 } 182 if (process_queue) { 183 al_unregister_event_source(process_queue , &timer_event_source); 184 al_destroy_event_queue(process_queue); 185 process_queue = 0; 186 } 187 if (timer) { 188 al_destroy_timer(timer); 189 timer = 0; 190 } 191 if (ethread) { 192 delete ethread; 193 ethread = 0; 194 } 195 spt = 0.0; 196} 197 198 199 200void Allegro5Timer::Start() { 201 SendTimerProcessMessage(EAGLE_MESSAGE_START_TIMER); 202 203 ALLEGRO_EVENT ev; 204 do { 205 al_wait_for_event(timer_queue , &ev); 206 } while (!((ev.type == EAGLE_EVENT_USER_START) && (ev.user.data1 == EAGLE_MESSAGE_START_TIMER))); 207} 208 209 210 211void Allegro5Timer::Stop() { 212 SendTimerProcessMessage(EAGLE_MESSAGE_STOP_TIMER); 213 214 ALLEGRO_EVENT ev; 215 do { 216 al_wait_for_event(timer_queue , &ev); 217 } while (!((ev.type == EAGLE_EVENT_USER_START) && (ev.user.data1 == EAGLE_MESSAGE_STOP_TIMER))); 218} 219 220 221 222void Allegro5Timer::Close() { 223 if (!ethread || (ethread && !ethread->Running())) {return;} 224 225 SendTimerProcessMessage(EAGLE_MESSAGE_CLOSE_TIMER); 226 227 // wait for message to be bounced back 228 ALLEGRO_EVENT ev; 229 do { 230 al_wait_for_event(timer_queue , &ev); 231 } while (!((ev.type == EAGLE_EVENT_USER_START) && (ev.user.data1 == EAGLE_MESSAGE_CLOSE_TIMER))); 232 233 ethread->Join(); 234} 235 236 237 238void Allegro5Timer::WaitForTick() { 239 if (timer_queue && timer) { 240 do { 241 ALLEGRO_EVENT e; 242 al_wait_for_event(timer_queue , &e); 243 if (e.type == ALLEGRO_EVENT_TIMER) { 244 Tick(al_get_time()); 245 break; 246 } 247 } while (true); 248 } 249 return; 250} 251 252 253 254void* Allegro5Timer::Source() { 255 return timer; 256} 257 258 259 260void Allegro5Timer::RefreshTimer() { 261 if (timer_queue && timer) { 262 ALLEGRO_EVENT ev; 263 while (al_get_next_event(timer_queue , &ev)) { 264 if (ev.type == ALLEGRO_EVENT_TIMER) { 265 Tick(al_get_time()); 266 } 267 } 268 } 269} 270 271 272 273bool Allegro5Timer::Valid() { 274 return timer && timer_queue && process_queue && ethread->Valid(); 275} 276 277 278 279long long int Allegro5Timer::Count() { 280 if (timer) {return al_get_timer_count(timer);} 281 return -1; 282} 283 284 285 286void Allegro5Timer::RegisterTimerInput(EagleEventHandler* event_handler) { 287/* 288 EAGLE_ASSERT(event_handler); 289 Allegro5EventHandler* a5_event_handler = dynamic_cast<Allegro5EventHandler*>(event_handler); 290 EAGLE_ASSERT(allegro_handler); 291 292 ALLEGRO_EVENT_QUEUE* allegro_queue = a5_event_handler->AllegroQueue(); 293 EAGLE_ASSERT(allegro_queue); 294 al_register_event_source(allegro_queue , al_get_timer_event_source(timer)); 295*/ 296 // so we don't have timers registered to queues and eagle timers registered as event sources at the same time 297 SubscribeListener(event_handler);/// TODO Convert to an event source 298}

And here's my main function :

int ThreadingTestMain(int argc , char** argv) {
   
   (void)argc;
   (void)argv;

   Allegro5System sys;
   sys.InitializeSystem();

   return 0;
}

The sys constructor just initializes everything to zero, and here's the code for InitializeSystem :

#SelectExpand
1 2bool EagleSystem::InitializeSystem() { 3 system_up = PrivateInitializeSystem(); 4 if (!system_up) { 5 OutputLog() << "Eagle : Failed to initialize the system." << std::endl; 6 } 7 else { 8 OutputLog() << "Eagle : Initialized system." << std::endl; 9 } 10 11 if (!input_handler) {input_handler = CreateInputHandler();} 12 if (!system_timer) {system_timer = CreateTimer();} 13 if (!system_queue) {system_queue = CreateEventHandler();} 14 15 system_up = (system_up && input_handler && system_timer && system_queue); 16 17 if (system_timer) { 18 bool created_system_timer = system_timer->Create(system_timer_rate); 19 system_up = system_up && created_system_timer; 20 if (created_system_timer) { 21 SetInputTimer(system_timer); 22 if (system_queue) { 23 system_timer->RegisterTimerInput(system_queue); 24 } 25 } 26 } 27 28 if (system_up) { 29 OutputLog() << "Eagle : Initialized the system state." << std::endl; 30 } 31 else { 32 OutputLog() << "Eagle : System state not fully initialized." << std::endl; 33 } 34 35 return system_up; 36}

So, my system creates a system timer, calls Create on it to create it, and then it gets destroyed by the destructor. Just simple code to test things right now.

I don't see what I'm doing to cause a crash in d3d_shutdown. Ideas?

Elias
Member #358
May 2000

What's EagleThread? Are maybe using an Allegro function on a thread not created by it?

--
"Either help out or stop whining" - Evert

Edgar Reynaldo
Member #8,592
May 2007
avatar

EagleThread is just a small wrapper around an ALLEGRO_THREAD. Allegro5Timer::Create new's an Allegro5Thread (the wrapper class) and calls Create on it to create a new thread. If it is successful, the thread is started and synchronized by message. The ALLEGRO_THREAD is destroyed in the destructor of Allegro5Thread, which is called by Allegro5Timer::Destroy after the thread has been joined.

Elias said:

Are maybe using an Allegro function on a thread not created by it?

No, all I use are ALLEGRO_THREADS at this point. If I write a driver for a different backend I might have to use pthreads, I don't know.

I don't understand, because all I do is initialize allegro and all the addons, then create a timer which uses an ALLEGRO_THREAD to monitor the ALLEGRO_EVENT_QUEUE that has subscribed to my ALLEGRO_TIMER. I initialize some resources, and then I shut down.

Where do you think the crash is coming from? A double free? On my part? On Allegro's part?

Elias
Member #358
May 2000

Does it also happen if you use a separate allegro.DLL instead of linking it in?

And just guessing at causes here...

--
"Either help out or stop whining" - Evert

Edgar Reynaldo
Member #8,592
May 2007
avatar

I'm currently linking dynamically to allegro, and to my library and to my backend. I built the static debug versions of them and tried it, and results were exactly the same.

Back in 5.0.0RC1 there was a crash in d3d_shutdown that was similar but I don't know if it was ever solved :
https://www.allegro.cc/forums/thread/605549/892332#target

I varied my code according to some ideas in that thread, and it still crashes in the same place.

#SelectExpand
1 2int ThreadingTestMain(int argc , char** argv) { 3 4 (void)argc; 5 (void)argv; 6 7 Allegro5System* sys = new Allegro5System(); 8 9 sys->InitializeSystem(); 10 11 delete sys; 12 13 al_uninstall_system(); 14 15 Sleep(3000); 16 17 return 0; 18}

Funny thing is, it doesn't crash during the manual call to al_uninstall_system but it does crash in al_uninstall_system when the exit routines run.

Program received signal SIGSEGV, Segmentation fault.
0x693df8b7 in d3d_shutdown () at C:\mingw\LIBS\A5GIT\allegro\src\win\d3d_disp.cpp:2604
2604       _al_d3d->Release();
(gdb) bt
#0  0x693df8b7 in d3d_shutdown () at C:\mingw\LIBS\A5GIT\allegro\src\win\d3d_disp.cpp:2604
#1  0x693cfa88 in win_shutdown () at C:\mingw\LIBS\A5GIT\allegro\src\win\wsystem.c:197
#2  0x6936fcd1 in shutdown_system_driver () at C:\mingw\LIBS\A5GIT\allegro\src\system.c:77
#3  0x69363fe1 in _al_run_exit_funcs () at C:\mingw\LIBS\A5GIT\allegro\src\exitfunc.c:92
#4  0x69370015 in al_uninstall_system () at C:\mingw\LIBS\A5GIT\allegro\src\system.c:302
#5  0x6ab41086 in __dll_exit () from c:\ctwoplus\progcode\eagle5gui\cbbuild\bin\eagle_a5d.dll
#6  0x6ab4110a in DllMainCRTStartup@12 () from c:\ctwoplus\progcode\eagle5gui\cbbuild\bin\eagle_a5d.dll
#7  0x77aaded4 in ntdll!RtlDefaultNpAcl () from C:\Windows\system32\ntdll.dll
#8  0x77a9a959 in ntdll!RtlExtendMemoryBlockLookaside () from C:\Windows\system32\ntdll.dll
#9  0x77a9a8db in ntdll!RtlExtendMemoryBlockLookaside () from C:\Windows\system32\ntdll.dll
#10 0x76933d77 in KERNEL32!ExitThread () from C:\Windows\system32\kernel32.dll
#11 0x00000000 in ?? ()
(gdb)

Edit

This does not crash :

   Allegro5System* sys = new Allegro5System();
   delete sys;

This crashes :

   Allegro5System* sys = new Allegro5System();
   sys->InitializeSystem();
   delete sys;

This does not crash :

   Allegro5System* sys = new Allegro5System();
   sys->InitializeSystem();
   delete sys;
   al_uninstall_system();

And now, this does not crash anymore when it did before :

   Allegro5System* sys = new Allegro5System();
   sys->InitializeSystem();
   delete sys;
   al_uninstall_system();
   Sleep(3000);

Anyone have any ideas how I should go about debugging this? I've already been down into every single code branch that InitializeSystem goes into, and I haven't seen anything wrong.

Trent Gamblin
Member #261
April 2000
avatar

I'm really hesitant to say anything here, because I don't know what's wrong and don't have much time to give any REAL help... but the first thing that comes to mind is unfreed D3D resources like shaders or VBOs or... anything like that?

Edgar Reynaldo
Member #8,592
May 2007
avatar

The only D3D or DX I'm using is whatever Allegro is using behind the scenes.

Why is D3D running when I haven't even opened a display yet?

I just tried ripping the guts out of EagleSystem::InitializeSystem and putting them in main and I can't reproduce the crash, even while executing pretty much the same code.

Evert
Member #794
November 2000
avatar

Probably not related (different platform for one), but a problem I ran into recently was that my program would crash when the main display was destroyed. This turned out to be due to destroying the parent bitmap, but not all of the child bitmaps. When the display was destroyed at the end of the program Allegro would try to turn these into memory bitmaps - and crash because the parent bitmap had already been destroyed.

Took me a while to find that one, so check if you might have a similar issue. Also, if you haven't already, try the OpenGL driver. If that works fine it may be a hint with the D3D driver, otherwise it's either something in your code, or at a higher level but within Allegro itself.

On Linux I find Valgrind a great help in situations like this, but I guess it isn't available for Windows?

EDIT: although, if the crash also happens with the OpenGL driver it may be reproducible on Linux...

Edgar Reynaldo
Member #8,592
May 2007
avatar

I wasn't even creating a display though. All I was calling was al_init(). Then create some allegro stuff and then destroy it all and shutdown allegro.

I could try changing the order I destroy things in and see if that helps. I thought all event sources unsubscribed themselves upon destruction, but maybe they don't. Well no al_destroy_event_queue says it auto de-registers. So I don't know why that would be it. Maybe my thread is still running but I join it in the destructor so it shouldn't be.

I really don't have any other idea what it might be.

Thomas Fjellstrom
Member #476
June 2000
avatar

It's either a really strange bug in allegro and/or windows or some kind of memory bug in your own code (this is usually the cause of strange crash bugs like this). Potentially a double free, or something is being corrupted.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Aikei_c
Member #14,871
January 2013
avatar

You still didn't tell us if the problem persists when you use opengl.
Anyway, you might actually have heap corruption, as Thomas pointed out. Try using crt heap checking functions.

Edgar Reynaldo
Member #8,592
May 2007
avatar

I said, I don't even create a display. I can't choose al_init(OPEN_GL). Do you mean you want me to create a display with OPEN_GL?

Heap corruption? I can look again I suppose. What are these crt heap checking functions you are talking about?

Thomas Fjellstrom
Member #476
June 2000
avatar

I think you can still change the "new" display driver.

I do find it odd that its trying to call any d3d "disp" code at all without any displays being created.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Aikei_c
Member #14,871
January 2013
avatar

That is probably not the most efficient way to check for heap corruption, however, I do the follwing.
First, you need to do this in the beginning of your program, better yet in the precompiled header:

#define CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

Then you place somewhere this line:

assert(_CrtCheckMemory());

If your heap is already corrupted at this point, it should break there. If it doesn't break at this assert, then put it further down your program. If it breaks at this assert, place your assert closer to the beginning of your program, and so on until you find the offending line.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Sorry, but MinGW 4.5.0 doesn't come with crtdbg.h or any other header with _CrtCheckMemory in it. Otherwise I would do it. They are specific to MSVC++, which I have installed, but I have never used it, and it would take me a long time to get my libraries set up with a solution. Also, MSVC++ wants me to register, and when I go to obtain a registration code, I am greeted with a Microsoft login. Yet another account to create.

Arthur Kalliokoski
Second in Command
February 2005
avatar

Also, MSVC++ wants me to register, and when I go to obtain a registration code, I am greeted with a Microsoft login. Yet another account to create.

I googled for a code without the intrusiveness.

“Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”

― Robert A. Heinlein

Aikei_c
Member #14,871
January 2013
avatar

I don't see why it's impossible to use crt function in gcc, since they are all part of msvcrt.dll which every windows user should have (with proper linking and headers). Anyway, I never used mingw, but there should be something specific to gcc/mingw or whatever, which can check if the heap is corrupted.
Maybe this question on stackoverflow can help you:
http://stackoverflow.com/questions/1761125/gcc-memory-leak-detection-equivalent-to-microsoft-crtdbg-h/1761159
EDIT: However, memory leaks which most of them seem to be talking about is not the same as heap corruption.
I still think that on windows you should somehow use windows crt functions and not linux-specific stuff which might actually never work on windows.
Ypu can also try to detect the offending code by shortening your program. Create the shortest possible example of your program which causes your problem. Like, try to replace your own timer with the standard allegro one, etc.

pkrcel
Member #14,001
February 2012

I don't think it would be that easy to link the Microsoft C Runtime DLL to a GCC-compiled program since GCC provides it's own C runtime....no? ???

Anyway Edgar, I don't have anythig REALLY useful here to say, but maybe are you able to reprodice the crash w/o Eagle related code?

Otherwise I'd definitely triple-check your Initialise System routines, particularly the Input and Event Handler (which sources are you registering there?)

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Thomas Fjellstrom
Member #476
June 2000
avatar

pkrcel said:

I don't think it would be that easy to link the Microsoft C Runtime DLL to a GCC-compiled program since GCC provides it's own C runtime....no? ???

Nope. MingW's entire purpose is to be a GCC that uses msvcrt.dll. Otherwise you get stuck with Cygwin and all of its nonsense.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

pkrcel
Member #14,001
February 2012

Ah of course that makes sense....so is it possible to import _CrtCheckMemory()?

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Thomas Fjellstrom
Member #476
June 2000
avatar

It probably is. You'd probably need to find the MSVC declaration and copy it into a gcc compatible format.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

pkrcel
Member #14,001
February 2012

Cool, should look into it.

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Evert
Member #794
November 2000
avatar

If you can post a complete program that shows the problem I can try compiling it in Linux and run it through valgrind. If there is something in your code it may show up there.

Cross platform develpmnt is a great way to find bugs.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Well, here is exactly what EagleSystem::InitializeSystem does :

#SelectExpand
1 2int ThreadingTestMain(int argc , char** argv) { 3 4 (void)argc; 5 (void)argv; 6 7 if (!al_init()) {return -1;} 8 9 EagleInputHandler* input = new Allegro5InputHandler(); 10 EagleTimer* timer = new Allegro5Timer(); 11 EagleEventHandler* queue = new Allegro5EventHandler(); 12 13 if (timer->Create(1.0)) { 14 OutputLog() << "Timer created" << std::endl; 15 SetInputTimer(timer); 16 timer->RegisterTimerInput(queue); 17 timer->Start(); 18 al_rest(5.0); 19 } 20 delete timer; 21 delete input; 22 delete queue; 23 24 return 0; 25}

and that doesn't crash at all. :/

Aikei_c said:

Create the shortest possible example of your program which causes your problem. Like, try to replace your own timer with the standard allegro one, etc.

Created separately none of my objects have problems. The code above is exactly what the line sys->InitializeSystem(); does.

pkrcel said:

but maybe are you able to reprodice the crash w/o Eagle related code?

No, I haven't been able to.

pkrcel said:

Otherwise I'd definitely triple-check your Initialise System routines, particularly the Input and Event Handler (which sources are you registering there?)

I have and I don't see anything wrong. No double frees, no leaks. I register the timer output with the event queue.

Evert said:

If you can post a complete program that shows the problem I can try compiling it in Linux and run it through valgrind. If there is something in your code it may show up there.

Thanks, but you would have to build my library and my allegro 5 backend to do so. I think I will migrate to building in my OpenSUSE VM so I can look for problems. And then I will create some CodeBlocks projects to build on Linux.

Evert said:

Cross platform development is a great way to find bugs.

I will try it out.

Go to: