Strange thread/pixmap behavior

BlitzMax Forums/BlitzMax Programming/Strange thread/pixmap behavior

Kernle 32DLL(Posted 2010) [#1]
Hi there,

I'm using BMax 1.41, and I'm tinkering around with threads for some time now. Yet, I pretty much failed in what I wanted to do: Create a thread to load pixmaps, while the main thread is showing kind of a load screen.

The problem here is the following: The program randomly crashes! And with random, I really mean random! Also, I always get a "EXCEPTION_ACCESS_VIOLATION" Message, regardless of Debugmode turned on or off, as such I can't even track the problem.

You can download the source code here; packed with some files which I can the program will crash at some point with (see proof.png).

http://dl.dropbox.com/u/387034/ThreadedPixmapTest.zip
Of course this is not the original source code, and its sole purpose is to produce said crash. Of course loading files in an endless loop is stupid, you don't need to point that out! And yes, it's not a memory overload, you can fill the loop with GC calls if you desire.

I went so far to circle the problem to the loadpixmap call, but then the same error occurred at another position :/ It all seems so random! Honestly, I'm out of ideas, anyone has some idea?

So long,
Kernle

PS: Interesting thing: If you replace the whole "CreateThread and While/Wend" part with the following code, the crash wont occur.

'More or less the "non-threaded" approach
Repeat
	loadGameContent(Null)
Forever


Edit: You can comment out the LoadPixmap call, to make the error occur even faster!

Last edited 2010

Last edited 2010


ima747(Posted 2010) [#2]
check my posts in the bug report forum regarding the garbage collector and threading. I think you're probably bumping up against the same problem that's made me put that development branch on hold until they address it.


Kernle 32DLL(Posted 2010) [#3]
figures, as I was able to solve the problem by some GC calls, but in my real programm, this doesnt work 100% :/ (sometimes, it crashes on the first pass on the first file :/)


BlitzSupport(Posted 2010) [#4]
Hmm, I got to 1169 passes with no failure (debug off), so it's hard to debug it. It certainly looks OK code-wise on a quick scan-through.

I disabled LoadPixmap and got to over 10000 calls with no failure too. Sorry! Anyone else?

I notice it's only creating one child thread, which just loops forever. What happens if you just call loadGameContent (Null), without a loop?


Kernle 32DLL(Posted 2010) [#5]
I get the crash at around pass 0 - 100, so if it didnt happen at 10000 - shit happens :/

As I said, the problem can be "eased" with random GC calls, but thats not a fix, thats gambling :/ Using 5 GC calls in total, I was able to reduce the crashing to once in around 20 startups, but it's still there.

Refering back to ima747's post, yes, it seems to be the same problem.

Last question BlitzSupport, which Bmax Version, and which OS did you use for your tests? Someone on the chat with the 1.38 Bmax was unable to reproduce the error as well, gonna check that tomorrow.

Edit1: BlitzSupport, the loop is there to "provoke" the crash to appear, as I said, it doesn't follow any real coding purpose

Edit2: Calling loadGameContent(Null), with a loop as described in the start post, does NOT cause the crash, using it without the loop is not the point (see Edit1)

Last edited 2010

Last edited 2010

Last edited 2010


BlitzSupport(Posted 2010) [#6]
I'm on 1.41 here, with Windows 7, and it's running without problems, sorry... :(


Kernle 32DLL(Posted 2010) [#7]
Tested some things out...

1.36 retail - no crash
1.38 retail - no crash
1.41 retail - no crash

So, the only thing I can think of now, is the fact that I compiled the BRL and Pub modules myself (MinGW 5.1.4 - GCC 3.4.5), so there would be no problem with the other modules I use, e.g. Brucys stuff (which need to be compiled anyway). What the...? And... why?

So long,
Kernle

PS: Using Windows 7 over here, too

Edit: Confirmed, retail 1.36, 1.38 and 1.41 don't cause the crash as intended by the given sourcecode. However, the crash still happens in my own project :/ Looking into the taskmanager shortly befor the crash, you can clearly see the characteristics for the bug ima747 described (memory beeing filled till a edgy degreee, and then eventueally freed). Someone more skilled then me reeeeally needs to look into this

Last edited 2010


ima747(Posted 2010) [#8]
Well it's not much good, but at least I feel less crazy now that someone else is feeling my pain...

I spent about 2weeks digging into the garbage collector (I think I documented most of my findings in the bug reports) but ultimately I don't understand why it's structured the way it is and I loose track of the flow. And it's not OS specific as I see essentially the same result on Mac and windows (vista and 7 personally as well as xp through a tester).

For the record using I think every bmax revision from 1.38 on up. I use the CE ide and brucy's bmk to cross compile but I've had the same results with standard ide and bmk directly compiling on windows.

For my specific uses I use brucy's free image module to load with but the results are the same when I use the standard load pixmap so it doesn't seem to be the loading routine. My testing all pointed squarely at the multithreaded garbage collector.

And just like Kernle has seen manual collection helps but is not a fix. It's very hard to get a simplified example to crash the same as a full project, and add to that that it's always somewhat random...


Kernle 32DLL(Posted 2010) [#9]
So, reading your bug report again, is this problem only releated to jpg and png files? If so, we could bypass the problem for now with other file formats, as free image offers a range wide enough I guess ;)

I have to admit tough, that I'm not such an image format expert, the only thing I could say is that bmp's are non-compressed images ;) (but as of that matter veeery big)


ima747(Posted 2010) [#10]
For me I have to support png and jpg as I'm loading user content and can't expect people to convert everything (totally impractical for my purposes).

I haven't explicitly tested uncompressed formats, but they should break the same way since the problem isn't in the image loader (using freeimage bypasses the build in loader all together) itself. However if you don't have to go through the decompression/decoding steps to load you will be creating less "trash" for the GC to clean up so you may see some improvement as a result, but again, probably not a solution. In line with cramming your code full of manual collects to try to reduce the overflow.


ima747(Posted 2010) [#11]
don't know if you saw, but I have an earlier related report as well.

http://www.blitzbasic.com/Community/posts.php?topic=91117

I think it's all connected, but can't get it out myself.


Kernle 32DLL(Posted 2010) [#12]
It all blows my mind @_@

While further testing some things, there was something which really caught my attention. The crashes I get don’t necessarily need to occur after a certain time with a given memory garbaging like ima747 suggested. Several times now, I even had the crash at pass 0, so the very first LoadPixmap call!!!

As for the "memory garbaging" problem... I had a quite.. well... uhm, hacky idea of bypassing the pixmap problem under the shower today. We know that the gc only has problems, if loadpixmap is called from a child thread. So, I wrote some messy little code that bypasses this, by "storing" the command in a stack, which is run by the main thread. Still, I get the crash, but I'm starting to realize that there is more running in the background than I can fit in my small mind :/

So long,
Kernle

NOTE: FOR TESTING ONLY, PRETTY HACKY

just replace your LoadPixmap calls with LoadPixmap_MT, and call "executeStack()" at least once in your main loop.



Edit~ Gramar control by word rocks...

Last edited 2010