Skip to content

Crash in _rmt_UnbindOpenGL #161

Open
@marcakafoddex

Description

@marcakafoddex

I am using:

  • Windows 10
  • Microsoft Visual Studio 2019 Preview 4.0
  • 64-bits build
  • Debug build

I build remotery (and the rest of my code) statically with the following defines:

  • RMT_USE_OPENGL=1
  • RMT_ENABLED=1

There are two scenarios.

SCENARIO 1:
This works fine.

  1. Main thread initializes Remotery: rmt_CreateGlobalInstance(&rmt);
  2. Various threads are started that do work using rmt_ScopedCPUSample. One of those threads is a renderer thread, which does rmt_BindOpenGL after activating the context, then uses rmt_ScopedOpenGLSample, and finally when shutting down calls rmt_UnbindOpenGL, and the deactivates the OpenGL context
  3. When all threads are gone but the main thread, the main thread calls rmt_DestroyGlobalInstance(rmt);

SCENARIO 2:
In this scenario the crash happens.

  1. Main thread initializes Remotery: rmt_CreateGlobalInstance(&rmt);
  2. Various threads are started that do work using rmt_ScopedCPUSample. One of those threads is a renderer thread, which does rmt_BindOpenGL after activating the context, then uses rmt_ScopedOpenGLSample, and finally when shutting down calls rmt_UnbindOpenGL, and the deactivates the OpenGL context
  3. A new set of threads is started, with a new renderer, but reusing the old OpenGL context
  4. As before in step 2, one of the new threads is the renderer thread, so it makes the OpenGL context current, calls rmt_BindOpenGL, and starts rendering. When shutting down, as before in 2, it calls rmt_UnbindOpenGL and then deactivates the OpenGL context.
  5. When all threads are gone but the main thread, the main thread calls rmt_DestroyGlobalInstance(rmt);

In this second scenario, the crash happens in the second rmt_UnbindOpenGL call in step 4, which is the second time I'm calling it. The call relevant callstack is short:

!FlattenSampleTree(Sample * sample, unsigned int * nb_samples) Line 4237 C
!FlattenSampleTree(Sample * sample, unsigned int * nb_samples) Line 4242 C
!FreeSampleTree(Sample * sample, ObjectAllocator * allocator) Line 4260 C
!FreePendingSampleTrees(Remotery * rmt, SampleType sample_type, Buffer * flush_samples) Line 5520 C
!_rmt_UnbindOpenGL() Line 6891 C

This is in the following code:

static ObjectLink* FlattenSampleTree(Sample* sample, rmtU32* nb_samples)
{
    Sample* child;
    ObjectLink* cur_link = &sample->Link;

    assert(sample != NULL);
    assert(nb_samples != NULL);

    *nb_samples += 1;
    sample->Link.next = (ObjectLink*)sample->first_child;  // CRASH HERE (!!!)

    // Link all children together
    for (child = sample->first_child; child != NULL; child = child->next_sibling)
    {
        ObjectLink* last_link = FlattenSampleTree(child, nb_samples);
        last_link->next = (ObjectLink*)child->next_sibling;
        cur_link = last_link;
    }

    // Clear child info
    sample->first_child = NULL;
    sample->last_child = NULL;
    sample->nb_children = 0;

    return cur_link;
}

The exception thrown is on the line marked "// CRASH HERE (!!!)"

Exception thrown: read access violation. sample was 0xFFFFFFFFFFFFFFD7.

According to the debugger, the Sample* sample variable going in is 0xdddddddddddddddd, indicating the memory was already freed.

It seems somehow rmt_UnbindOpenGL doesn't expect to be called more than once?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions