"Windows Exception!" "Exception Access Violation"

BlitzMax Forums/BlitzMax Programming/"Windows Exception!" "Exception Access Violation"

Gabriel(Posted 2010) [#1]
I've recently started getting a popup titled "Windows Exception" with the message "Exception Access Violation" in it. The debugger always points to a line calling a BlitzMax type constructor. (EG: v = new vector or q = new quaternion )

It's not random, but at the same time, it only happens occasionally and it appears to only occur in certain situations. It happens in both debug and release.

I can't think of any reason for a type constructor to throw an exception, but I can't get the debugger to give me anything else. I've updated and rebuilt everything from scratch but there seems to be no way of getting a more helpful indication from the debugger of what is happening or why. Before I updated BlitzMax it was an unhandled memory exception error instead.

So yeah, not really sure where I can go with this. Normally when you get bugs but the debugger isn't reporting them right, it's because the error is in a constructor or a destructor, but the types that error don't have constructors and errors in destructors don't reliably crash the debugger on the same line over and over again. They're more random than that. This falls on several different lines but all the lines are the same calls. So I don't think it's that this time. No idea where I should begin or what I can do though.

Any thoughts?


Nate the Great(Posted 2010) [#2]
I found this happens to me when I forget to close TStreams or try to close null TStreams


Gabriel(Posted 2010) [#3]
Well it happens midway through playing a level, so I don't *think* I'm closing any TStreams at this point, but it's the best lead I have, so I'll have a scour around and see if there are any TStreams being closed around the time this happens. Thanks for the tip.


Nate the Great(Posted 2010) [#4]
well I have a feeling it could be cause by lots of other things, thats just what ive been programming with a lot recently... It does seem like a general error... and it also happens to some of my programs with known memory leaks when I close my laptop and it goes into sleep mode then comes back out, it will throw the same error. I havent gotten this error at all until recently however so maybe its something new?


GfK(Posted 2010) [#5]
I had this error a lot when I was using threads. Basically I got it whenever there was a runtime error that wasn't in the main thread.

Haven't seen it once since I stopped using threads.


Gabriel(Posted 2010) [#6]
Yeah, I don't think the debugger is really set up to work with threads. I'm not using threads at all though, nor the threadsafe GC, although I am considering it just to see if it makes a difference. Don't really want the performance hit though, so I'm trying to trim down the amount of objects I create and destroy.

Shot in the dark: I create and destroy a lot of objects. Is it at all possible I could just be overpowering the GC in some way? I mean my total memory usage is quite moderate, coming in around 250mb, but if I have a ton of objects, could I have filled up the GC's buffers or have overrun the stack? I mean the objects are in the heap, but presumably each reference is on the stack. If this is remotely possible, is there any way to confirm it? Can I get numbers back regarding the GC or the stack and what would I be looking for?


grable(Posted 2010) [#7]
Its allso something that youl get with a stack overflow (too deep recursion depth).
If the debugger enters on different lines each time it might be another stack related error, like wrong calling convention.


Gabriel(Posted 2010) [#8]
Nope. It always ends on creating a new object, and specifically only a vector or quaternion, although those are by far the most commonly created objects. It isn't always the same line but it's always a call to the constructor of one of those objects.

EDIT: Having removed many of the dynamic object creation calls, it has now started throwing the error on BlitzMax's own Types like TMapEnumerator. Still on the constructor though.

Stack overflow was where I was thinking with overpowering the GC or creating too many objects, but I'm sure I'm not doing any deep recursion.


skidracer(Posted 2010) [#9]
Are you able to select (double click) anything in the stack trace in the debug tree after clicking OK on the error requester?


Gabriel(Posted 2010) [#10]
Yes, I am. Would all that have gone if the stack was overflowing?


skidracer(Posted 2010) [#11]
So the line featuring the new is the culprit and not something inside the constructor?

The debugger assumes application is at fault in an error so you may need to double click on the last stack trace entry to see the offending line of code in any module function your app was calling at the time.


Gabriel(Posted 2010) [#12]
Yeah, the line featuring the new is always the culprit. My two constructors are empty.

I was aware of the situation with the debugger. The last stack trace entry is definitely the line featuring the new.


Dreamora(Posted 2010) [#13]
Are you running in threaded mode?
Did you add the "threaded debugging modification"?


Gabriel(Posted 2010) [#14]
No, and no. Until last night I was using an old BMax version which did not even have threading. Last night I upgraded but I am still not enabling threading.

I'd consider trying it, mind you. If only to see if the different GC handles things any differently.

EDIT: Ok, I have tried it, and it won't compile. Two of my modules are throwing "cannot find interface for blah.blah" errors. With threading disabled, everything compiles and runs fine. Presumably there is a command line setting for bmk which builds modules with threading enabled? What/where is that?


Gabriel(Posted 2010) [#15]
Well I found the command line option for threading (-h) and I've managed to compile my game with the threaded GC now. For comparison, with the old GC, I was managing to crash the game at least once every five minutes (repeating the same action until it crashed). Now doing the exact same thing with the threaded GC, I have been at it for two hours without a crash.

So at the very least, it seems that the threaded GC has mitigated the problem, if not solved it altogether. So I guess I really was breaking the GC? Not sure how though, as my efforts to create and destroy less objects just made the GC crash more often. Is there anything else I can do now or do I just have to use the threaded GC and hope it's good enough?


Corum(Posted 2010) [#16]
Hi Gabriel.
I think I have the same problem.
Please, Can you explain how you've baked this workaround?
Thanks.


Gabriel(Posted 2010) [#17]
All I did was enable threading in the build settings. If you use Blide as I do, it's next to debug build and quick build. I assume it's similarly positioned in BlitzMax.

With threading enabled, I guess BlitzMax is forced to use the new thread-safe garbage collector.

If you get compiling errors, you need to compile the modules with the threaded flag enabled. You can probably do this from the ide too, but I compiled from the command line:

bmk makemods -h modulenamespace.modulename


I'm not offering this as a 100% solution, but I've gone from crashes every 5 mins to no crashes in several hours, so it definitely seems to be an improvement. The threaded GC is slower though, so expect to make some optimizations to help it out.


TaskMaster(Posted 2010) [#18]
Wow, I can't see how using the threaded GC "solved" your problem. Generally it causes problems.

My guess is, the threaded GC just isn't collecting correctly and missing your errors.


Corum(Posted 2010) [#19]
@Gabriel: thanks for your reply. It's exactly what I do, but my MT application crashes always under same circumstances.
Which version of BMax are you using?

Reading the Mac OS crash reports, I usually get a trail made of:
- bbGCAllocObject
- allocMem
- collectMem
- bbObjectFree <----- Crash occurs here.

Such calls are executed to load several images from a zip file, which I incbin into my application.
I read its contents by using the Koriolis' zipstream module.

If I revert to BMax 1.34, I have no issues at all. I'm considering to rollback.
Bye.


Gabriel(Posted 2010) [#20]
Which version of BMax are you using?

I'm using the very latest. 1.37. I haven't tried any intermediate versions since 1.30. I wasn't able to obtain any crash report, so I can't say if they were similar or not.


Gabriel(Posted 2010) [#21]
My guess is, the threaded GC just isn't collecting correctly and missing your errors.

It's certainly possible that the new GC is masking problems in the old GC or in BlitzMax itself, but there's very little I can directly do about BlitzMax or the GC, and a potential memory leak is preferable to a crash every time. Having said that, I've tracked memory use and I don't see any indication that it's leaking. It's true that the new GC uses a lot more memory for the same amount of objects - possibly because of the way it counts/stores the references - but there's no indication that it's not being freed again when you exit the level.

Of course, it would be nice if I could find the real nature of the problem and somehow get it fixed, but there's not much to go on with crashes on creating an object. It's not as though I can deliver 350 source files and nearly 1GB of media to Mark and ask him to look into it.

Incidentally, if you have any tips on what things tend to cause the new GC problems, that might well be helpful in further pinning down where exactly this problem is.


TaskMaster(Posted 2010) [#22]
I wish I did have tips, but I have never looked into the internal workings of the GC, so I am no help there. I also have not had the opportunity to really do anything serious with multi-threading.


ziggy(Posted 2010) [#23]
Have you recompiled any third party modules you are using after the change to 1.37? Just in case...


Gabriel(Posted 2010) [#24]
Yes, all of them.


beanage(Posted 2010) [#25]
I am really not that sort of lowlvl guru, but when i had this very message i just did this to solve it, and it worked: Verify what you are doing at New() or Delete(), make SURE you close ALL streams, dont use the TManagedRamStream streams, dont do arbitrary memextends, make sure you aint use misdirected pointers or memcopy where memmove is expected or bad parameters for those ... so far.


Gabriel(Posted 2010) [#26]
Sadly, I've pretty much concluded that there is no bug in any of my code. The threaded GC seems to be collecting all of my objects exactly as the old GC did, so I'm forced to conclude that the old GC is either broken or can't cope with the number of objects/references I'm using. The threaded GC is a bit slow so I'm going to need to do some low-level optimizations to avoid pushing it so hard. Particularly with TV3D, which needlessly creates a lot of objects you don't need for very long, but I can't really fix those without breaking with the API for everyone else, so it'll have to be done via some additional "private" methods.


Arowx(Posted 2010) [#27]
Could it be some kind of memory allocation error, it's just I've written a simple countdown timer, clock app that I leave running for days which used to work fine, until I started messing with it recently and new builds (1.36) kept eating up massive amounts of memory.

The build using 1.37 now stays stable with regard to memory but keeps getting the Windows Exception, error when left running for a couple of hours.

And it only get's it when calling grabimage, hence my hunch that it is related to some kind of memory allocation error?

I'm going to run it with the three seperate graphics drivers to see if they make any difference if it's the same for all 3 then the problem is most likey something to do with memory allocation and the GC!


Arowx(Posted 2010) [#28]
I'm just running a simple app that creates thousands of test objects and releases thousands of object randomly, it's been running for about an hour now without an exception and has allocated millions of objects...



So this looks solid, should I try more complex memory structures within the objects e.g. arrays, banks, ramstreams, images

Or more complex interconnections between objects e.g. lists of objects within objects?


Arowx(Posted 2010) [#29]
Well as soon as I added a bank the exceptions started to appear.
As CreateBank only calls MemAlloc() I've trimmed my code to this it's guaranteed to generate a windows Exception very quickly...



I get the following debug output prior to a fail...
DebugLog:1731 :103
DebugLog:1732 :103
DebugLog:1733 :104


Which would appear to be about the 1,733 Mb of allocated space, so is this error just a memory leak within blitzmax?


Arowx(Posted 2010) [#30]
Minor update well you would expect about 1.7Gb of allocated space to have an impact so I've tried again with a 1 byte MemAlloc limit, it takes a lot longer but the Access Violation Exception still occurs but this time when the GC Memory reaches about 758Mb or 24.28 Million objects?

When I've googled the exception it turns up Heap Corruption, in effect the program is trying to use memory that has not been correctly allocated or deallocated!


TaskMaster(Posted 2010) [#31]
My guess is that you are somehow hitting the 4gb memory space limit on all 32-bit apps.


Arowx(Posted 2010) [#32]
Don't think it's that as I've tried the same code but using malloc directly to allocate the memory, now blitzmax ads a few bytes but I was request a megabyte at a time now ...


MemAlloc version ... 1,755 objects created before access violation
malloc verion ... 267,763 objects created before access violation





Now the only difference under the hood that I can see is MemAlloc adding an additional 20 bytes to the allocation for alignment, and storing the address pointer in that, although there is a lot of bitwise logic going on!

What do you get?


grable(Posted 2010) [#33]
I tried your test.. and i only get an access violation when using MemAlloc, not malloc.

The maximum seems to be 1.9GB even though i have roughly 2.2GB free.

Oh, and you should check the return value of malloc. as the test will keep going forever (or until the GC heap is used, which will take a long time)


grable(Posted 2010) [#34]
Ive tracked the "bug" in MemAlloc down to not checking for NULL from malloc, ending in a write to an invalid pointer.

So using malloc/free instead and checking its the return value should more gracefully handle out of memory errors.
Though this isnt perfect, as malloc might not return NULL under all conditions and platforms.

EDIT: ive traced it further into bbGCAllocObject that calls MemAlloc in single threaded mode, and of course Strings which also calls MemAlloc (in both modes).


Arowx(Posted 2010) [#35]
Gable your spot on regarding the malloc when I run with with malloc(size+20) where the 20 bytes matches the 20 added under the hood in MemAlloc and test for a null return value I get exactly the same results!

OK so the problem appears to be a memory allocation error that could be triggered by the creation of a New object/string/bank or pixmap!

The trouble is that it's not being picked up and issues as a memory allocation error so everyone is looking all over the place for it.

But it should take the allocation of lot's of memory before the heap fills up, does that mean there are more memory leaks in BlitzMax?


grable(Posted 2010) [#36]
does that mean there are more memory leaks in BlitzMax?

Not necessarily, the ACCESS_VIOLATION is a general exception for anything unknown.
Usually reads and writes to bad pointers.. so it could still be anything if you keep getting those :/

EDIT: as a side note, have you tried running your executable in a real debugger? that will usually show you the instruction doing the bad stuff, allowing you to trace upward through the chain to figure out what its doing wrong, and more importantly where ;)


Arowx(Posted 2010) [#37]
That sounds cool, where can I get a real debugger that I can link into my blitzmax exe?


grable(Posted 2010) [#38]
I Use IDA, but OllyDebug isnt bad either and theres always GDB for the terminal junkies.
And there is no linking needed, you run the release-mode binary via the debugger.
You will have to know a little x86 assembly to know whats what though.


ShadowTurtle(Posted 2010) [#39]
My guess is that you are somehow hitting the 4gb memory space limit on all 32-bit apps.

No. HandyRPG use only 19MB-22MB (win7 64bit, task manager). The error is every the same, on the same clicks. By the way.. the error is not available in release mode compile.

I think this has to do a little with membit, event handling, timer & (forgotten code?) none-threading.

I uploaded a test version (w/source) of my app. Save & binary export are cutted out.

Link: http://www.shadowturtle.de/files/misc/handyrpg-critical-bmax-bug-testfield.zip (<- the link does not more exists since 2010-04-30)

With this you can take a real test. It is 1/1 BlitzPlus code. BlitzPlus commands are wrapped to use maxgui commands. BlitzPlus maked never errors like this!

Error 1:
start handyrpg.bmx
load final_pogopuschel.hpj
into the treeview: click: items -> SelfHealth
error: EXCEPTION_ACCESS_VIOLATION

Error 2:
start handyrpg.bmx
load final_pogopuschel.hpj
into the treeview: click: items -> Playernone
error: EXCEPTION_SINGLE_STEP

Error 3:
start handyrpg.bmx
load final_pogopuschel.hpj
into the treeview: click: items -> PlyrHealth
into the treeview: click: items -> Seil (engl. rope)
error "PlyrHealth": Windows error: App does not more work. Program closed.
error "Seil": Same as "PlyrHealth" + compatibility wizard (windows 7).

Anti-Error 1:
start handyrpg.bmx
load final_pogopuschel.hpj
into the treeview: click: items -> LittlePaper
No error comes. There is no graphic defined. Next steps:
click: use Žon useŽ
click: "Select/Edit graphic"
click: "select"
No error comes. The graphic is perfectly displayed.


Another things...



Sorry, Czar Flavius. I think this should not a solution. The bug should be fixed.


1. i think there is a hard blitzmax bug/problem going on.. Oo

2. System: Windows 7, 64bit, AMD 2-core. I do use _not_ the maxide community edition. I do use the original maxide. BlitzMax V1.37.

3. i deleted BlitzMax V1.36 complete before i huv installed V1.37. I deleted all damn files.

4. errors like "EXCEPTION_ACCESS_VIOLATION", "EXCEPTION_PRIV_INSTRUCTION" are _not_ random!

5. add the following error into the list:
"Unhandled Exception:setMemBit error: membit already set"
screenshot:


6. in release-mode my program make _no_ problems. No memory leaks. No memory bugs. No etc.

7. Error structure (debug output, MaxIDE). See screenshot:


8. Complete informations (goes to the technical guy @ brl ^^):
'Function ObjectEnumerator' in "/mod/brl.mod/linkedlist.mod/linkedlist.bmx"
Type "Type TList", Line: 89
Marked code: "Local enum:TListEnum=New TListEnum"
Line: 404

'Method FlushBrushes(pRecurse:Int = True)' in "/mod/maxgui.mod/win32/win32maxguiex.mod/win32maxguiex.bmx"
Type "Type TWindowsPanel Extends TWindowsGadget", Line: 4101
Marked code: "For Local tmpGadget:TWindowsGadget = EachIn kids"
Line: 4312

'Method FlushBrushes(pRecurse:Int = True)' in "/mod/maxgui.mod/win32/win32maxguiex.mod/win32maxguiex.bmx"
Type "Type TWindowsWindow Extends TWindowsGadget", Line: 1343
Marked code: "tmpGadget.FlushBrushes()"
Line: 1787

'Method WndProc(hwnd,msg,wp,lp)' in "/mod/maxgui.mod/win32/win32maxguiex.mod/win32maxguiex.bmx"
Type "Type TWindowsGadget Extends TGadget", Line: 831
Marked code: "FlushBrushes()" (on event "WM_WINDOWPOSCHANGING"!?)
Line: 1077
^ WTF!?!?!? The event WM_WINDOWPOSCHANGING was never started! No window resize etc..! I clicked on a treeview entry.
^ I think this error has with the event system (memory leak in debug mode?) to do.

'Method WndProc(hwnd,msg,wp,lp)' in "/mod/maxgui.mod/win32/win32maxguiex.mod/win32maxguiex.bmx"
Type "Type TWindowsWindow Extends TWindowsGadget", Line: 1343
Marked code: "Return Super.WndProc(hwnd,msg,wp,lp)"
Line: 1732
^ can the error to do with "Super"!? (see top)

'Function ClassWndProc(hwnd,msg,wp,lp) "win32"' in "/mod/maxgui.mod/win32/win32maxguiex.mod/win32maxguiex.bmx"
Type "Type TWindowsGUIDriver Extends TMaxGUIDriver", Line: 279
Marked code: "If owner Return owner.WndProc(hwnd,msg,wp,lp)"
Line: 495

'Function HandyRPG' (there is no main-function or main-type around the app) in "handyrpg.bmx"
Type: None.
Marked code: "playeritem_actualgui()"
By the way...
playeritem_actualgui does ..
... no window resize. (see comment at top)
... no send events
... no getting events
... no resize gadgets
so.. what is going on with pointing on the following code section (debug-mode)!?
Select msg
	Case WM_WINDOWPOSCHANGING ' <= "WM_WINDOWPOSCHANGING" must be started.
		FlushBrushes() ' <= this is the next way, on going producing the error/bug.
EndSelect


9. The bug must also positioned into the blitzmax's own debugger source wich handles events. Is a pointer setted wrong?




ImaginaryHuman(Posted 2010) [#40]
I am getting an exception access violation when running a blitz app on Vista 64-bit but the error does not occur on Vista 32-bit.

It's probably still something relating to blitzmax as I don't see why it would perform any differently on the two systems, although maybe influence from other apps, allocated memory, etc might play a part. I am going to try rolling back BMX to an earlier version, and try the threaded garbage collector. I also noticed I think that the problem sometimes goes away in debug mode.


ima747(Posted 2010) [#41]
personally I would look into your windows install, error check your HD, virus scan, close down background apps etc. If it runs fine on a 32 bit system then it should, in theory, be fine, since a 64bit OS will just run it in 32bit mode anyway since bmax only compiles to 32bit... so I would look at the specific system that has the problem. However your code/mods/etc. might be exacerbating some underlying issue with that system (such as using a bad sector of memory on a less than perfect chip...), but I wouldn't expect the bitedness (I declare YE a word!) of the OS to be the main culprit.