0

While refactoring some code, I've run into an issue with heap corruption.

namespace GPU
{
    struct ShaderStage
    {
    public:
        ShaderStage(ShaderStageType, const Path&);
        ShaderStage() = default;
        [Default copy/move constructors]

        ShaderStageType StageType = {};
        std::string Source = {};
        std::filesystem::path BasePath = {};
    };

    struct Shader
    {
    public:
        Shader(const Path& v, const Path& f);
        Shader() = default;
        [Default copy/move constructors]

        ShaderStage VertexStage = {};
        ShaderStage FragmentStage = {};
    };

    ShaderStage::ShaderStage(ShaderStageType type, const std::filesystem::path& path) : StageType(type), BasePath(path)
    {
        Source = [any string, loads file in this case];
    };

    Shader::Shader(const Path& v, const Path& f) :
        VertexStage(ShaderStageType::Vertex, v),
        FragmentStage(ShaderStageType::Fragment, f)
    {
    };
}

namespace GL
{
    class Shader final : protected GPU::Shader
    {
    public:
        Shader(gE::Window* window, GPU::Shader&&);
        Shader() = default;
    };

    Shader::Shader(gE::Window* window, GPU::Shader&& INTERNAL_SETTINGS) : GPU::Shader(move(INTERNAL_SETTINGS))
    {
                [Actually constructs GL::ShaderStage, but I can replicate the issue with just moving GPU::ShaderStage around]
        GPU::ShaderStage frag = move(FragmentStage);
        GPU::ShaderStage vert = move(VertexStage);

        FragmentStage = move(frag);
        VertexStage = move(vert);
    }
}

This is how I construct the object:

GPU::Shader shaderSettings("Resource/Shader/skybox.vert", "Resource/Shader/skybox.frag");

[GL::Shader _skyboxShader = {}]
_skyboxShader = GL::Shader(window, move(shaderSettings));
[SIGTRAP when _skyboxShader goes out of scope]

Placement new works:

GPU::Shader shaderSettings("Resource/Shader/skybox.vert", "Resource/Shader/skybox.frag");

[GL::Shader _skyboxShader = {}]
_skyboxShader.~Shader();
new(&_skyboxShader) GL::Shader(window, move(shaderSettings));
[No error]

I'd like to think I'm experienced with c++, and this whole thing is just bizzare. I've gone through multiple passes of debugging which yielded no results.

5
  • What does move do? Commented Nov 20, 2024 at 3:04
  • 3
    Heap corruption issues frequently are caused by code far away from and not related to the code where the symptom turns up. You might try a memory analysis tool like valgrind. We're not likely to be able to help here unless you can post a minimal reproducible example. Commented Nov 20, 2024 at 3:09
  • 2
    From the code you've supplied, and symptoms you have described, it is impossible to say. There's a distinct possibility that the cause of heap corruption is in completely unrelated code, and your refactoring happens to have expose a symptom as a side effect (e.g. because of refactoring, organisation of memory used by your program as a whole has changed, and whatever is being tromped now gives an observable symptom). Even though it seems counter-intuitive, you may need to look for the cause in code that you haven't changed. Commented Nov 20, 2024 at 3:44
  • I agree to the prior comments, the symptoms look like out of bounds memory access that corrupts random data, those can be extremely difficult to detect manually. Any address sanitizer tool should be able to detect where the problem comes from. Search for one which fits to your build environment. GCC and Visual Studio provide address sanitizers (the GCC sanitizer is good, the visual studio one I did not test yet). Valgrind is/was a good tool but is unfortunately a bit outdated. Commented Nov 20, 2024 at 13:57
  • I tried using Application Verifier which didn't seem to find anything. I'll try the GCC sanitizers. Commented Nov 20, 2024 at 14:14

1 Answer 1

0

I switched to MSVC and the issue seemingly disappeared; Address Sanitizer still finds no issues. Using my own array class in place of std::string and std::filesystem::path works too.

I don't know if I should trust my own findings (maybe a gcc bug?) or I just keep winning the heap corruption lottery after switching to MSVC.

Sign up to request clarification or add additional context in comments.

2 Comments

If you used third party libraries were all of them compiled with the exact same compiler that you used for your code? This could be caused by using incompatible libraries.
More than likely it is not a gcc bug, but is in code somewhere in your program. The "joys" of bad pointer operations include (1) code can seem to work correctly sometimes (2) the bug can show up in different ways (including presenting no observable symptoms) with different compilers or - even with the same compiler - different optimisation or other compilation options (3) the code where a symptom is observed can be completely unrelated to the code that caused the problem (4) the symptom can appear, or disappear, due to changing code that doesn't cause the problem.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.