Weird crashes with TMap.Values()

BlitzMax Forums/BlitzMax Programming/Weird crashes with TMap.Values()

grable(Posted 2015) [#1]
Im having a bit of trouble with when enumerating over TMap.Values(), for some reason a Null value creeps into the tree and crashes the enumerator on TNode.NextNode() (it gets it when tracing the nodes parents).

But this only happens in Release mode, in Debug mode everything runs as expected :(

And the weirder part is that if i enumerate over TNodes instead, it also works as expected, even in Release mode!

Also this only happens in NON-Threaded mode, so might have something to do with refcounting.

Im not doing anything special either, just using generated strings as keys...

Anyway, could someone try this piece of code and see if they get the same problem? Atleast then id know if its something with my setup or otherwise.


typemap.bmx


typemap.txt



Derron(Posted 2015) [#2]
I had the "null" problem on a "NextNode()" last friday - when I freshly installed BlitzMax 1.50 on a Linux Mint (15 or 16?) 32Bit. The error did not happen when compiling it on my desktop (1.50, Mint 17,64Bit).


On the desktop I use the "maxmod"-variant of TMap. According to the changes it does not do change things (but it adds "concurrent modification"-checks).


But: I did not have issues on the 32bit-linux-laptop when directly working with "values()". It only segfaulted when using "themap.copy().Values()"



So if the reason is the same, some people wont see your problem while others might experience it.

Your example did not segfault here on 64bit Mint17. Tried release, release+threaded, debug.



bye
Ron


grable(Posted 2015) [#3]
Hmm so this might be something relating to 32-bit OS then, as im on Windows 7 32-bit right now.
Never ran into this before on my main 64-bit rig.

And i should probably add that a GCCollect anywhere crashes too,
so it seems more and more to do with the single threaded GC really.


Brucey(Posted 2015) [#4]
Assuming nothing has changed with BlitzMax, I wonder why it would suddenly start to behave erratically...


grable(Posted 2015) [#5]
Yeah it is kinda weird, and i use TMap all the time so should have noticed something like this sooner.

I even tried it on the OpenSource version to no avail.

Only thing ive done is make it run on Mingw 5.1.0..
But il try a recompile on this machine, as i just copied the precompiled stuff over. Maybe gcc did something funny, who knows :p


Derron(Posted 2015) [#6]
@grable

do you use prebuild modules or ones you recompiled? Vanilla "fasm" or an updated one?


@Brucey
I think so too ... but if it crashes, it crashes and most of us are left "puzzled" then.


bye
Ron


grable(Posted 2015) [#7]
@Derron

I always recompile when i update to a new Mingw, so they should be fine.
And the version of fasm i use is 1.71.39.


grable(Posted 2015) [#8]
Well that took its sweet time. 1 hour for a recompile, and that doesnt include thread mode!

Sadly it did nothing :(


Derron(Posted 2015) [#9]
You should only need to recompile the modules you are using... only wxmax is what takes forever here.


Does your example crash with a "vanilla blitzmax 1.50"-compilation ?


bye
Ron


Floyd(Posted 2015) [#10]
Does your example crash with a "vanilla blitzmax 1.50"-compilation ?

It crashes with my vanilla BlitzMax 1.50, and with 1.48 as well.

Both use FASM 1.69.14 and I have not changed/rebuilt anything since they were installed.


Brucey(Posted 2015) [#11]
Crashes on OS X too.

Runs fine in NG though :-)


GW(Posted 2015) [#12]
Not sure if it helps but inserting this
Local _count% = 0
For Local m:TIrTypeMapping = EachIn map.TypeMaps.Values()
	_count:+ 1
Next
'// continue to the offending loop
'// unchanged
For Local m:TIrTypeMapping = EachIn map.TypeMaps.Values()
'For Local n:TNode = EachIn map.TypeMaps
'	Local m:TIrTypeMapping = TIrTypeMapping(n._value)
	Local s:String = m.ToName()[.. 15] + m.ToString()
	WriteStdout s[.. 42]
	If m.Code Then
		WriteStdout " -> "
		WriteStdout m.Code
	EndIf
	WriteStdout "~n"
Next



just above your value iteration (~ln:360) stops the crashing.

strange, I've never had Map blow up on me before.


Derron(Posted 2015) [#13]
This sounds as if the iterator is creating some trouble.

NextNode() fails (in my case "_node" was null then in the debug tree) .


bye
Ron


grable(Posted 2015) [#14]
Ive done some more tests, and have more or less figured out why it happens. Exactly where though i have no idea :/

Things that does NOT crash:

1. GCSuspend before the loop, and GCResume/GCCollect afterwards.
2. Making the container type Global instead of Local.
3. Using container type as an argument to a function.
4. Adding a field to TNodeEnumerator that contains the TMap itself.

This leads me to believe that its a combination of the Single-Threaded GC and For-EachIn enumeration that frees the container type in the middle of the loop.

The easiest fix without changing the compiler is to just add a field to the enumerator to make sure its map can never go out of scope early.

But a proper fix would be better...