Results 1 to 10 of 30

Thread: Yet another segfault (a.k.a. Darkhog is a total noob)

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    PGD Staff / News Reporter phibermon's Avatar
    Join Date
    Sep 2009
    Location
    England
    Posts
    524
    Ok found it and sort of fixed it.

    Oh yeah sorry, I should tell you shouldn't I?

    procedure TSprite.UpdateMask;

    if ActualMaskBitmap<>nil then al_destroy_bitmap(ActualMaskBitmap); //preventing memory leak

    Replace with :

    if ActualMaskBitmap<>nil then
    begin
    al_destroy_bitmap(ActualMaskBitmap);
    ActualMaskBitmap := nil;
    end;



    -----


    the actual error happens on the al_bitmap_mask_color calls in collide in masked_collision.pas :

    function collide( Sprite1: TSprite; Sprite2: TSprite):boolean;

    mask1 := al_bitmap_mask_color(sprite1.ActualMaskBitmap);
    mask2 := al_bitmap_mask_color(sprite2.ActualMaskBitmap);


    I noted on the crash that ActualMaskBitmap was an invalid reference (just junk data at the time of the call)

    However this points to a much more serious problem as it would appear that you've got more than one thread executing code across your program at the same time, the error is actually appears to be happening because al_destroy_bitmap(ActualMaskBitmap); is called in UpdateMask and then before it can be created again, the collide function tries to use it with al_bitmap_mask_color.

    My fix isn't a real fix and it can still crash inbetween these two calls :

    al_destroy_bitmap(ActualMaskBitmap);
    ActualMaskBitmap := nil;

    before the pointer is set to nil. al_bitmap_mask_color must contain code that just breaks out if it gets a null pointer.

    I'd reccomend that you stop the multi-thredded execution (find out how and where it's doing that, allegro is probably firing off events or something in a seperate thread, something like that)

    and stop re-creating these masks all the time, you should store all the masks for all the frames as well.

    if you *never* called al_destroy_bitmap() on these masks, IE don't call updatemasks, find some other way of doing it then you might find it never crashes. I should expect my 'fix' would eventually crash, it'd just be pure chance if the al_bitmap_mask_color function gets called before that reference is set to nil.

    But unless you really know what you're doing, you're only going to hit even harder problems with multi-threadded execution as your code base grows in size.


    EDIT: I can confirm that sooner or later (20 seconds or so of continual sprite intersection in my case but could literally be at any moment) it'll break again. I'd eat my hat if I'm wrong about the threadding. I shall post pictures too


    EDIT EDIT : you're using Allegro timers. They are seperate threads (at least on the windows platform, not in DOS). there's your source. You should use mutexes etc to synchronize access to shared resources such as these bitmap masks or otherwise stop using the timers.
    Last edited by phibermon; 27-07-2013 at 08:55 PM.
    When the moon hits your eye like a big pizza pie - that's an extinction level impact event.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •