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.
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.
Share Improve this question edited Nov 20, 2024 at 3:03 John Kugelman 362k69 gold badges552 silver badges596 bronze badges asked Nov 20, 2024 at 3:00 garlfingarlfin 111 bronze badge 5 |1 Answer
Reset to default 0I 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.
move
do? – 3CxEZiVlQ Commented Nov 20, 2024 at 3:04