bmx-ng / bcc

A next-generation bcc parser for BlitzMax
zlib License
33 stars 12 forks source link

Array out of bounds allowed? #663

Open DruggedBunny opened 4 months ago

DruggedBunny commented 4 months ago

Hi all,

While playing with Mark's LibSGD, I realised by chance that I was accessing an array incorrectly, and narrowed it down to this:

SuperStrict

Local sound:Int [7] ' Booms

For Local num:Int = 1 To 10
    sound [num] = num
    Print sound [num]
Next

Print sound [10]

BlitzMax vanilla gives the expected:

"Unhandled Exception:Attempt to index array element beyond array length"

In NG, this compiles and prints output for each index!

Kerntrick commented 4 months ago

You're probably compiling in 'Release' mode. If you compile in 'Debug' mode the array access will get caught.
This is normal behavior. Release mode is for performance and so it has less 'training-wheels' to slow it down.

DruggedBunny commented 4 months ago

Oh, OK -- I'd have imagined it would crash anyway! (I suppose it maybe allocates more memory than needed?)

If it's intended then fair enough anyway.

GWRon commented 4 months ago

It crashes as soon as the "foreign" memory contains something you are tampering.

If you simply read from that memory position and only use it for eg printing out a number...in most cases this will not crash. But if you use it for writing..it will tamper content of some other object/property and this might lead to a crash/EAV.

DruggedBunny commented 4 months ago

Interesting! But is this not writing to 'foreign' memory?

For Local num:Int = 1 To 10
    sound [num] = num

I'd really expect this to crash either way -- and I rarely use the debugger! (Print FTW.) I was just surprised this had been working at all.

GWRon commented 4 months ago

it does not crash for everyone, as it depends on "what comes after the array". Memory layout isdone by "not you" on your computer. You might even think of seeing "valid" values there - because in your special computer environment the memory "behind" was used for something similar before.

You might remember having "garbage images" when creating pixmaps without "clear pixels". It just uses some stuff still existing in this moment. So you either had "trash" there, or sometimes part of the desktop, or other images - it always depends on what "was there before" and how things could be interpreted ("pixel colors", "sound data"...).

If every of your array accesses were guarded then performance would drop significantly. And thus means, as @Kerntrick already wrote, only Debug builds will do this for you to help finding exactly such issues. In "release builds" you are on your own. This is the same behaviour in legacy and NG.

DruggedBunny commented 4 months ago

Yeah, that's the thing, though -- I'm expecting it to crash, not save me from my mistake.

It just seems odd to me that it doesn't crash like in vanilla -- but you're right, vanilla was in Debug mode (hence the output "Unhandled Exception:Attempt to index array element beyond array length"), whereas in release mode it does the expected crash ("EXCEPTION_ACCESS_VIOLATION") -- but that is really what I'm expecting to see here, rather than being protected from it.

I was surprised when I realised it wasn't crashing, but if this is expected then fair enough -- it just didn't seem right. (That's why I'm imagining it allocates more memory than it needs, so isn't hitting illegal memory.)