Spellcaster Studios

Make it happen…

Day 4: Light!

Well, it seems the bug is almost fixed… As I suspected, it was a buffer overflow somewhere, but the place was unlikely: the particle system… In particular, this was the offending piece of code:

if (!_vb)
{
    _vb=create_vertex_buffer((int32_t)(_particles.size()+PSBUFFER)*4);
    _ib=create_index_buffer((int32_t)(_particles.size()+PSBUFFER)*6);
    _allocated=(int32_t)_particles.size()+PSBUFFER;
}
else
{
    // Check if they have space
    if ((size_t)_allocated<_particles.size())
    {
        size_t n_part=_allocated*2;
        // Resize buffer
        delete _vb;
        delete _ib;
        _vb=create_vertex_buffer(n_part*4);
        _ib=create_index_buffer(n_part*6);
        _allocated=n_part;
    }
}

Basically, this piece of code initialized the vertex buffer for the particle system… If there isn’t one, it initializes it with the number of particles (plus a fixed number, so it has room to grow). I need 4 vertex and 6 index per particle, so that’s why I multiply there…

Can you spot the error? Tick, tock…

Well, imagine that in the start, you have 40 particles on the buffer… Then on the next update, you have 100… This should grow, right?

Yep, it does, but not enough… Since I’m doubling the size of the array per iteration, instead of looking at the particle count, I’d grow the array to 80 particles, not the necessary 100, but the rest of the code would write 100 particles…

So, buffer overflow… Ideally, this should cause an access violation (because I’d be writing in memory that didn’t belong to my process), but in most of cases in the game flow, I’ll be writing on top of other memory in the same process, corrupting the data structures necessary for the heap to allocated and free stuff properly… So this error would only be detected when an allocation/deletion goes wrong (which might be seconds after the actual corruption takes place)…

The corrected code:

    if (!_vb)
    {
        _vb=create_vertex_buffer((int32_t)(_particles.size()+PSBUFFER)*4);
        _ib=create_index_buffer((int32_t)(_particles.size()+PSBUFFER)*6);
        _allocated=(int32_t)_particles.size()+PSBUFFER;
    }
    else
    {
        // Check if they have space
        if ((size_t)_allocated<_particles.size())
        {
            size_t n_part=_particles.size()*2;
            // Resize buffer
            delete _vb;
            delete _ib;
            _vb=create_vertex_buffer(n_part*4);
            _ib=create_index_buffer(n_part*6);
            _allocated=n_part;
        }
    }

This was a nightmare to find… But it’s still not all… I’m pretty sure I still have heap corruption issues, since I still have crashes (it just takes way longer!), so I’ll have to see if I’m not doing this same silly mistake in other places (all hail the twin gods of Copy and Paste)…

Finally some good news… I’ll be away from the Internet for a few days, but I’m taking the computer to continue development, so there might not be a blog post for a couple of days (unless I upload it with my 3G connection)…

Now listening to “Alternative 4” by “Anathema”

Comment