Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » Allegro crash bug

This thread is locked; no one can reply to it. rss feed Print
Allegro crash bug
Puck6633
Member #4,668
June 2004

I was working on a project of mine and came across a curious bug where it would crash on exit. After running it through gdb with a debug compile of allegro I found the the problem seems to be either in allegro/src/mouse.c lines 477 to 488 of show_mouse(), or somewhere in draw_mouse.

The problem is that I'm drawing the mouse to a bitmap I created (so I can have objects overlapping the mouse), then blitting that bitmap to the screen. The problem arises at the end of the program, where I free the bitmap I normally draw the mouse to and return from main. This triggers a call to allegro_exit(), which calls shutdown_gfx(), which calls set_gfx_mode(), which in turn calls show_mouse(NULL), which then tries to draw to the destroyed bitmap BEFORE checking if it's argument is NULL.

To better illustrate the sequence of function calls, here's the backtrace:
#0 0x67462c64 in blit_loop_blitter ()
#1 0xe40f017f in ?? ()
#2 0x67406021 in blit (src=0xb33a80, dest=0xa2c494, s_x=0, s_y=0, d_x=159, d_y=119, w=16, h=16) at src/blit.c:739
#3 0x67447392 in draw_mouse (remove=-1, add=0) at src/mouse.c:231
#4 0x67447b2e in show_mouse (bmp=0x0) at src/mouse.c:532
#5 0x67429621 in set_gfx_mode (card=-1, w=0, h=0, v_w=0, v_h=0) at src/graphics.c:665
#6 0x67428f61 in shutdown_gfx () at src/graphics.c:446
#7 0x6740157d in allegro_exit () at src/allegro.c:409
#8 0x6740128b in allegro_exit_stub () at src/allegro.c:293
#9 0x7800396a in _libwinmm_a_iname ()

And some example C code that triggers the problem:

1#include <allegro.h>
2 
3BITMAP *canvas;
4 
5int main(int argc, char *argv[]) {
6 allegro_init();
7 install_timer();
8 install_mouse();
9 install_keyboard();
10 set_color_depth(32);
11 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
12 canvas = create_bitmap(SCREEN_W, SCREEN_H);
13
14 while (!key[KEY_ESC]) {
15 show_mouse(NULL);
16 clear_to_color(canvas, makecol(128, 128, 128));
17 //Do our drawing
18 show_mouse(canvas);
19 //Possibly do more drawing
20
21 blit(canvas, screen, 0, 0, 0, 0, canvas->w, canvas->h);
22 }
23
24 destroy_bitmap(canvas);
25 return 0;
26}
27END_OF_MAIN()

Compile with 'gcc <filename>.c -o <filename> -lalleg'

It's not a serious bug, and calling show_mouse(NULL) before destroying the bitmap prevents the crash, but there it is anyway. :)

[Edit] It just occurred to me that "show_mouse() bug" would have been a much better title, but I can't seem to change the topic, sorry. :(

flares
Member #3,463
April 2003
avatar

All you said was right. i had the same problem, you need to call show_mouse(NULL) before you destroy the bitmap, other wise the mouse updater tries to draw the mouse to a NULL bitmap. I think this happens because the way the mouse updater draws the mouse is only when it changes. if you move the mouse as you are exiting after you destroy the bitmap then it will crash because you try to draw to NULL, and NULL dont like it.

[nonnus29]Plus the api is crap ... I'd rather chew broken glass then code with those.

Evert
Member #794
November 2000
avatar

Yes, this is a problem. Allegro stores a copy of the screen pointer in teh mouse routines, so that it's possible that the screen is destroyed while the mouse cursor is being drawn onto it.
I'm not sure, but this may have been fixed (I haven't heard about this bug in a while now)... what version of Allegro are you using?

Puck6633
Member #4,668
June 2004

I'm using 4.1.17 WIP, but it actually doesn't seem to be that the bitmap is being destroyed whiel the mouse is being drawn to it, it seems to be that calling show_mouse(NULL) draws the pointer one last time to the bitmap you last drew to. (At least if I'm reading the code correctly, though the comments seem to confirm it) in particular this bit of code in show_mouse() seems to be at fault:

/* Remove the mouse cursor */
   if (_mouse_screen) {
      acquire_bitmap(_mouse_screen);

      if (gfx_capabilities & GFX_HW_CURSOR) {
   gfx_driver->hide_mouse();
   gfx_capabilities &= ~(GFX_HW_CURSOR|GFX_SYSTEM_CURSOR);
      }
      else
   draw_mouse(TRUE, FALSE);

      release_bitmap(_mouse_screen);
   }

changing the "else" to an "else if (bmp)" fixed it for me, though I can't say for certain it won't cause other problems, particlarly with hardware cursors (which I can't test).

Go to: