Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Return code 1

This thread is locked; no one can reply to it. rss feed Print
Return code 1
Aikei_c
Member #14,871
January 2013
avatar

After my application ends, it returns 1 which should mean that something isn't right. However, I can't tell what it is.
Probably I am not freeing something correctly. In allegro.log I have the following text near the end:

d3d D d3d_disp.cpp:904 d3d_destroy_display_internals [ 41.01223] waiting for display 00327FF0's thread to end
d3d W d3d_disp.cpp:616 d3d_destroy_device [ 41.02325] d3d_destroy_device: ref count not 0
d3d I d3d_disp.cpp:1522 d3d_display_thread_proc [ 41.07369] d3d display thread exits

is this the cause that code 1 is returned? and if so, what is it caused by? I guess that something still referencing d3d device has to do with it. But what? Should I destroy all the bitmaps before destroying the allegro_display? or vice versa? and what about the fonts?
I am pretty sure that I eventually free everything. Should I care at all about this return code?

Trent Gamblin
Member #261
April 2000
avatar

Do you have a return statement in your main function?

Aikei_c
Member #14,871
January 2013
avatar

No. And it's void main() anyway. I guess allegro substitutes it for something and it's allegro's return code, not mine.

Dizzy Egg
Member #10,824
March 2009
avatar

;D

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Aikei_c
Member #14,871
January 2013
avatar

What's funny here, Dizzy Egg?

Dizzy Egg
Member #10,824
March 2009
avatar

What did you expect if you declare your main as void? A nice '0' to be returned??? >:(

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Arvidsson
Member #4,603
May 2004

Aikei_c
Member #14,871
January 2013
avatar

Well. Thank you very much for noting that. I changed that.
However, i think it did return 0 in the past if all the threads had returned 0.
But the problem still stays: last thread returns 1. (I am not creating threads myself, these are all allegro threads). Should I worry about it?
--
I am pretty sure it's the d3d thread mentioned in the log.

Trent Gamblin
Member #261
April 2000
avatar

It's not the d3d thing, that's just a warning. You say you're seeing the return code of 1 in the debugger? What else does the debugger say? Is there a crash or an assertion or exception thrown?

Aikei_c
Member #14,871
January 2013
avatar

No. No crash and nothing is mentioned. That's why I went to allegro.log and that's the only thing that I found here which seemed abnormal.
Yes I see the return code in the debugger after everything ends.
By the way, it's pretty strange. Now I changed everything to the way you say it should be, with int main(int argc, char **argv) and ending with return 0.
But the funny thing is, the application still returns 1.

The thread 0x934 has exited with code 0 (0x0).
'Mirrord.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\powrprof.dll'
The thread 0x10f8 has exited with code 0 (0x0).
The thread 0xce8 has exited with code 1 (0x1).
'Mirrord.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\nvd3dum.dll'
'Mirrord.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\d3d9.dll'
'Mirrord.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\d3d8thk.dll'
No memory leaks detected.
Visual Leak Detector is now exiting.
The program '[3456] Mirrord.exe' has exited with code 1 (0x1).

Arthur Kalliokoski
Second in Command
February 2005
avatar

How about putting a message box or a printf("bye\n"); just before that final return 0? Does it show that message on exit? Of course you'd have to run it from a console to see a printf.

“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'm pretty sure it runs up to the very end and executes every last line.
But I did what you asked. Yes, the message is shown.

UPDATE: I attached allegro.log to the first post.

Audric
Member #907
January 2001

Could be a signal handler called "on exit" because a SIGSEGV happens for example and/or something installed by atexit() crashes. Can you try putting a breakpoint on libc's exit() ? If something is calling exit(1), you'd see in the call stack.

Aikei_c
Member #14,871
January 2013
avatar

Hello, Audric and thank you for your input.
Could you explain to me, how do I put a breakpoint on libc's exit?

UPDATE: OK, I did it this way: I made an empty function, put a breakpoint on it and then passed it to atexit().
The strange thing is that when I check value of the argument "code" of the exit(int code) function, which is up the call stack, it shows 0 in the debugger. Up to the end. And then visual studio says it exited with code 1...

I'm not sure I put the breakpoint when you suggested, though.

Trent Gamblin
Member #261
April 2000
avatar

Try setting a breakpoint anywhere after your program starts up fully. Check which threads are running (don't know how in VS, but should be possible.) Not their id/address and what they're doing. Then when the app exits check which thread that returns 1 corresponds to the one you checked on earlier.

Audric
Member #907
January 2001

Your test already shows that the issue happens after main() returns, after it executes the function you hooked on atexit(). Maybe then it executes another atexit() function that was registered before yours (by a library, usually).
I don't know about Visual Studio's debugger for C language, though if it has similar options as for C#, be sure to check in Debug/Exception menu: "Break on ..." everything : signals, caught exception, uncaught exception, runtime errors... everything it proposes.
If you do find a way to make it break on system functions of your choice, try stopping abort() in addition to exit().

Aikei_c
Member #14,871
January 2013
avatar

Trent Gamblin
I have the following threads:

2928 0 Main Thread name: Mirrord.exe!MirrorApp::Init Normal

5676 0 Worker Thread name: GdiPlus.dll!DllRefCountSafeThreadThunk() location: GdiPlus.dll!BackgroundThreadProc Normal

1556 0 Worker Thread name: msvcr110d.dll!_threadstartex location: allegro-5.0.8-monolith-md-debug.dll!501c453e Normal

5684 0 Worker Thread name: nvd3dum.dll thread location: nvd3dum.dll!67319d84 Above Normal

When the program ends, the 0x162c thread returns with code 1, that is the second thread 5676.

Audric
The problem is, the return code 0 stays up to the end. I mean, I step through the whole program up to the line __crtExitProcess(code); after which the program ends. And even there it shows "the program exited with code 1", when I step over the program ends with code 1. I can't step into this function itself thought I get thrown into assembly.
How is that even possible? Could it be some memory corruption?
I have no idea what else to enable, I think it should break at every exception.
I think I found a way to break at function by its name, and I added breakpoints on abort and exit functions, but it doest break on abort. It breaks on exit, though.

UPDATE:
It seems that the application returns 1 when the last thread returns 1. If the last thread to end isn't this GDI thread, then I get return code 0.
Moreover, I just used this tutorial http://wiki.allegro.cc/index.php?title=Basic_tutorial_on_loading_and_showing_images and the GDI thread there also returns 1. However, the application itself returns what it is told to return.

Trent Gamblin
Member #261
April 2000
avatar

Can you set a breakpoint in _al_shutdown_gdiplus? What happens if you don't init the image addon?

Aikei_c
Member #14,871
January 2013
avatar

If I don't init the image addon the return code is 0.
Yes, I can put a breakpoint there. What am I looking for over there?

Gdiplus::GdiplusShutdown(gdiplusToken);

the gdiplusToken is 37445138

Trent Gamblin
Member #261
April 2000
avatar

I'm not sure why the GdiPlus thread is returning 1. A temporary solution might be to call al_shutdown_image_addon before returning from main.

Aikei_c
Member #14,871
January 2013
avatar

Shutting image addon down manually doesn't kill the gdi thread and it still only gets destroyed at exit (with code 1). Maybe some other addon uses it too?

Trent Gamblin
Member #261
April 2000
avatar

What about a patch like this?

diff --git a/addons/image/iio.c b/addons/image/iio.c
index d98716e..6ecbfe5 100644
--- a/addons/image/iio.c
+++ b/addons/image/iio.c
@@ -128,6 +128,10 @@ bool al_init_image_addon(void)
 void al_shutdown_image_addon(void)
 {
    iio_inited = false;
+
+#ifdef ALLEGRO_CFG_IIO_HAVE_GDIPLUS
+   _al_shutdown_gdiplus();
+#endif
 }

Aikei_c
Member #14,871
January 2013
avatar

I'll probably have to compile allegro myself for that, right? or I could just place shutdown_gdi myself in my code?
Anyway, thank you very much, Trent. It seems it's nothing serious I should care about.

Trent Gamblin
Member #261
April 2000
avatar

You can try calling _al_shutdown_gdiplus() yourself (you may have to declare it.)

Audric
Member #907
January 2001

Aikei_c said:

It seems it's nothing serious I should care about.

This could be the tip of the iceberg in a allegro bug, so thank you for your persistence.

Go to: