Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Why does this crash?
#1
Can anyone explain why the code below crashes?

Sometimes the Y value gets as high as a few hundred, other times just barely past 10.

I would have chalked this up as running out of memory but the random crash points has me confused. The picture I'm using is attached below.

Code: (Select All)
OPTION _EXPLICIT

TYPE TYPE_PIXEL
    hard AS LONG ' hardware image
    soft AS LONG ' software image
    ox AS INTEGER
    oy AS INTEGER
    x AS INTEGER
    y AS INTEGER
    xdir AS SINGLE
    ydir AS SINGLE

END TYPE

DIM Pixel(1280, 720) AS TYPE_PIXEL
DIM Picture AS LONG
DIM x AS INTEGER
DIM y AS INTEGER

SCREEN _NEWIMAGE(1280, 720, 32)
Picture = _LOADIMAGE("picture.png", 32)

_SOURCE Picture
FOR y = 0 TO 719
    FOR x = 0 TO 1279
        Pixel(x, y).soft = _NEWIMAGE(1, 1, 32)
        _DEST Pixel(x, y).soft
        PSET (0, 0), POINT(x, y)
        Pixel(x, y).hard = _COPYIMAGE(Pixel(x, y).soft, 33)
        Pixel(x, y).ox = x
        Pixel(x, y).oy = y

        _DEST 0 '                                        temporarily print values to figure
        PRINT x, y, Pixel(x, y).soft, Pixel(x, y).hard '  out why this crashes

    NEXT x
NEXT y


Attached Files Image(s)
   
There are two ways to write error-free programs; only the third one works.
QB64 Tutorial
Reply
#2
TerryRitchie, could you comment out sections of code to narrow down what could be giving you problems when run?
Reply
#3
I'd guess it's all those Pixel(x, y).soft = _NewImage(1, 1, 32) images which aren't freed up?  When I add a _FreeImage Pixel(x, y).soft at the end (just before the NEXT x) it doesn't crash.

- Dav

Find my programs here in Dav's QB64 Corner
Reply
#4
(09-18-2023, 10:08 PM)Dav Wrote: I'd guess it's all those Pixel(x, y).soft = _NewImage(1, 1, 32) images which aren't freed up?  When I add a _FreeImage Pixel(x, y).soft at the end (just before the NEXT x) it doesn't crash.

- Dav
Yep, you're right, how odd. However, I want to keep the software version of the pixel too for the demo I have in mind. Hmm, I'll play around with this.
There are two ways to write error-free programs; only the third one works.
QB64 Tutorial
Reply
#5
Here is something else odd I'm noticing. The program seems to be crashing during a software surface redraw. See the image below.


Attached Files Image(s)
   
There are two ways to write error-free programs; only the third one works.
QB64 Tutorial
Reply
#6
Ok, even if I try to create 1280x720 (921600) individual software images of 1x1 pixel with nothing else going on the program still crashes at random points. Something is not right here.
There are two ways to write error-free programs; only the third one works.
QB64 Tutorial
Reply
#7
I have written a similar program and became convinced QB64PE doesn't like arrays of an user-defined type involved with long integers to be used for image handles.

On Slackel Linux, I wrote a program which was supposed to take a screenshot of the desktop at the time (clumsily with "scrot" command-line tool) and do a "meltdown" business like stuff from that cheap "Matrix" movie that keeps being recalled. Now I have to go find that program in my backups. It works now, because I was forced to allocate a separate array of long integers to hold the image handles, apart from an array of an UDT.

This contribution is actually useless in this thread but I had to voice it out.
Reply
#8
I can't open nearly that many 1x1 images either.  Here's code I was playing with.  When I increase the image size it crashes quicker too, so there is a memory limit I'm reaching.  So It may be just the regular running out of memory issue. But why that limit is different for different runs I dunno, maybe an OS memory management thing?  I'm just throwing out guesses....

- Dav

Code: (Select All)

Screen _NewImage(800, 600, 32)
Dim img&(500000)
For t& = 1 To 500000
    Print t&
    img&(t&) = _NewImage(1, 1, 32) 'increase pix size, it crashes quicker.
Next

Find my programs here in Dav's QB64 Corner
Reply
#9
I modified the above program to add a `_LIMIT 10000` inside the loop, and caused it to print every 1000 iterations. It gave up at about 300 thousand. But I needed to keep Firefox in memory and myself logged into this site, so...
Reply
#10
Unfortunately it's just a pretty straight forward bug in QB64, you can see it here.

Basically what's happening is that the program starts with a buffer that can hold 4096 images, and once you create more than that it will "resize" the buffer to be larger by another 4096. That resize process involves creating a new buffer, copying the contents, and then freeing the previous buffer. The code does attempt to update the pointers to images, hence the `update existing img pointers to new locations` comment, but unfortunately that's not good enough because the display thread is using `display_page` with no synchronization. The end result is that the display thread can end up reading from `display_page` when it still points to the old free'd buffer of images and that leads to it randomly blowing up.

I can't offer an actual fix at the moment beyond just avoiding that many images, but if you change `IMG_BUFFERSIZE` in `libqb.cpp` to be larger than the number of images your program will use then you can avoid the issue.
Reply




Users browsing this thread: 1 Guest(s)