Jump to content

CreateActor causing heap corruption when used on a Camera


Drew_Benton
 Share

Go to solution Solved by Drew_Benton,

Recommended Posts

UltraEngine Version: 1.0.1

Adding a CameraControls component to the Camera now seems to cause a heap corruption error on exit.

The code I'm using is simply:

auto actor = CreateActor(camera);
actor->AddComponent<CameraControls>();

For example:

#include "UltraEngine.h"
#include "ComponentSystem.h"

using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    //Get the displays
    auto displays = GetDisplays();

    //Create a window
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR);

    //Create a framebuffer
    auto framebuffer = CreateFramebuffer(window);

    //Create a world
    auto world = CreateWorld();

    //Create a camera
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.125);
    camera->SetFov(70);
    camera->Move(0, 2, -8);

    auto actor = CreateActor(camera);
    actor->AddComponent<CameraControls>();

    //Create light
    auto light = CreateBoxLight(world);
    light->SetRotation(45, 35, 0);
    light->SetRange(-10, 10);

    //Load FreeImage plugin
    auto plugin = LoadPlugin("Plugins/FITextureLoader");

    //Model by PixelMannen
    //https://opengameart.org/content/fox-and-shiba
    auto model = LoadModel(world, "https://github.com/UltraEngine/Documentation/raw/master/Assets/Models/Characters/Fox.glb");
    model->SetScale(0.05);
    model->Animate(1);
    model->SetRotation(0, -90, 0);

    auto neck = model->skeleton->FindBone("b_Neck_04");
    Vec3 rotation;

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        world->Update();

        rotation.y = Cos(float(Millisecs()) / 10.0f) * 65.0f;
        neck->SetRotation(rotation);

        world->Render(framebuffer);
    }
    return 0;
}

This example, which was working in the YT video, now also exhibits this same issue: https://www.ultraengine.com/learn/Terrain_SetMaterial?lang=cpp

Message:

image.png.f969139f0c4b5be2b2289fbd5994f860.png

Stack Trace:

 	ucrtbased.dll!00007ffd7e4fce3d()	Unknown
 	ucrtbased.dll!00007ffd7e500275()	Unknown
>	Ultra1_d.exe!operator delete(void * block) Line 38	C++
 	Ultra1_d.exe!operator delete(void * block, unsigned __int64 __formal) Line 32	C++
 	Ultra1_d.exe!std::_Ref_count_obj2<Actor>::`scalar deleting destructor'(unsigned int)	C++
 	Ultra1_d.exe!std::_Ref_count_obj2<Actor>::_Delete_this() Line 2053	C++
 	Ultra1_d.exe!std::_Ref_count_base::_Decwref() Line 1119	C++
 	Ultra1_d.exe!std::_Ptr_base<UltraEngine::ActorBase>::_Decwref() Line 1399	C++
 	Ultra1_d.exe!std::weak_ptr<UltraEngine::ActorBase>::~weak_ptr<UltraEngine::ActorBase>() Line 2996	C++
 	Ultra1_d.exe!UltraEngine::Entity::~Entity(void)	Unknown
 	Ultra1_d.exe!UltraEngine::Camera::~Camera(void)	Unknown
 	Ultra1_d.exe!UltraEngine::Camera::`vector deleting destructor'(unsigned int)	Unknown
 	Ultra1_d.exe!std::_Destroy_in_place<class UltraEngine::Camera>(class UltraEngine::Camera &)	Unknown
 	Ultra1_d.exe!std::_Ref_count_obj2<class UltraEngine::Camera>::_Destroy(void)	Unknown
 	Ultra1_d.exe!std::_Ref_count_base::_Decref() Line 1111	C++
 	Ultra1_d.exe!std::_Ptr_base<UltraEngine::Camera>::_Decref() Line 1337	C++
 	Ultra1_d.exe!std::shared_ptr<UltraEngine::Camera>::~shared_ptr<UltraEngine::Camera>() Line 1620	C++
 	Ultra1_d.exe!main(int argc, const char * * argv) Line 57	C++
 	Ultra1_d.exe!invoke_main() Line 79	C++
 	Ultra1_d.exe!__scrt_common_main_seh() Line 288	C++
 	Ultra1_d.exe!__scrt_common_main() Line 331	C++
 	Ultra1_d.exe!mainCRTStartup(void * __formal) Line 17	C++
 	kernel32.dll!00007ffeb3b87614()	Unknown
 	ntdll.dll!00007ffeb52226a1()	Unknown

Thanks!

  • Thanks 1
Link to comment
Share on other sites

I just tried this on a new project and did not experience any problem. I also uninstalled and reinstalled 1.0.1, cleaned the project, ran it again, and it worked correctly. 

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

I made some changes, and now I am testing by running the Shutdown function in a game loop without any errors, so it's really functioning more like a "Sync all threads" function. I will have an update soon of 1.0.1.

  • Like 2

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

An update for 1.0.1 is up now. I made some adjustments to the shutdown procedure that may eliminate your problem. You can also call UltraEngine::Core::Shutdown() yourself, as long as it is the last command your program calls, but it should not be needed.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Thank you for looking into this so quickly.

I updated and tried again, but still had the same issue, so I tried what SpiderPig suggested:

 

5 hours ago, SpiderPig said:

Hello, maybe try a fresh project as your code worked for me. 🤔 Or try updating your current project?

A fresh project seems to fix the issue.

I know just how finicky C++ can get when code generation is involved (noticed components need to be in the components folder for the preprocessor), so as I continue to experiment, I'll try this first from now on if I run into the problem again.

Thanks!

Link to comment
Share on other sites

I would be interested in trying the project, if you would like to upload it. You're saying one copy of the program crashes, and another does not, on the same computer. It seems like that indicates something is wrong in that project somehow.

I assume you did a clean and rebuild on this project?

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

26 minutes ago, Josh said:

I would be interested in trying the project, if you would like to upload it. You're saying one copy of the program crashes, and another does not, on the same computer. It seems like that indicates something is wrong in that project somehow.

I assume you did a clean and rebuild on this project?

I found the exact, replicable problem as I was zipping it up to attach for you.

At one point, I wanted to switch between a few of the different examples, so I renamed "main.cpp" to "main2.cpp" and excluded it from my Solution.

I then added a new "main.cpp", but I just now noticed Visual Studio put it in the root folder by default, instead of the "Source" folder.

That was what was causing the problem, because as soon as I move "main.cpp" back into the "Source" folder, the issue goes away. Moving it back one level above "Source" triggers the same error again.

Mystery solved, I'm still getting used to the new required project layouts and whatnot, so I'll have to remember to keep track of where new files get put!

Link to comment
Share on other sites

4 minutes ago, Drew_Benton said:

Mystery solved, I'm still getting used to the new required project layouts and whatnot, so I'll have to remember to keep track of where new files get put!

FYI, you can config the preprocessor to your desired project layout. Run the application in PowerShell with -help for more information.

  • Thanks 1

Cyclone - Ultra Game System - Component PreprocessorTex2TGA - Darkness Awaits Template (Leadwerks)

If you like my work, consider supporting me on Patreon!

Link to comment
Share on other sites

8 minutes ago, Drew_Benton said:

That was what was causing the problem, because as soon as I move "main.cpp" back into the "Source" folder, the issue goes away. Moving it back one level above "Source" triggers the same error again.

 

Well, that's not necessarily the cause. I don't know how that would even effect the program.

If you have something like a random memory overwrite then a small unrelated change to the program or compilation step could cause it to appear fixed, simply because the memory on your computer is shifting around a different way.

 

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

  • Solution
14 minutes ago, Josh said:

Well, that's not necessarily the cause. I don't know how that would even effect the program.

If you have something like a random memory overwrite then a small unrelated change to the program or compilation step could cause it to appear fixed, simply because the memory on your computer is shifting around a different way.

You're right.

Upon digging even more and deleting various cached files and removing extra source code, the real problem was that my 'ComponentSystem.h' was generated once, but didn't get regenerated again by the pre-processor:

// This file is generated by the pre-processor. Do not modify it.
// Generated on: Wed Jan 18 00:48:19 2023

However, my 'ComponentSystem.cpp' file did:

// This file is generated by the pre-processor. Do not modify it.
// Generated on: Wed Jan 18 10:31:21 2023

I realized this was the actual problem when I was getting compile errors for code that wasn't even in the project anymore.

Upon deleting 'ComponentSystem.h' and getting it re-generated, the error now goes away.

Link to comment
Share on other sites

20 minutes ago, Josh said:

Hmmmm, I don't remember adding date stamps into the comments like that, but it's a really smart idea. I must be more clever than I thought!

I added that. 😢

  • Thanks 2

Cyclone - Ultra Game System - Component PreprocessorTex2TGA - Darkness Awaits Template (Leadwerks)

If you like my work, consider supporting me on Patreon!

Link to comment
Share on other sites

17 minutes ago, reepblue said:

I added that. 😢

It waa very good idea. I wonder if the header date or some other value could be declared in both the header and CPP file would work to ensure the two are always in sync? Like, in the component constructor an Assert could compare the two values and make sure they are the same.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

It's possible with a string comparison. After the file time check, we can have it read line 2 of each file via stream to see if it's a 100% match. If it doesn't match, it regenerates both files. We can move the timestamp to line 1 to make it much simpler.

I can look into this tonight. We should also dedicate the project to use the full engine to avoid code conflicts, but on the other hand, building it with UAK is sooo much faster. I'm leaving that call up to you.

Cyclone - Ultra Game System - Component PreprocessorTex2TGA - Darkness Awaits Template (Leadwerks)

If you like my work, consider supporting me on Patreon!

Link to comment
Share on other sites

@Josh

I submitted a pull request for the pre-processor. I've reproduced this situation and the update responds accordingly. 

Quote

The application will now read the first line of ComponentSystem.cpp and ComponentSystem.h to see if the timestamps match. If not, the rebuild bool is tripped. This is to fix this from ever happening: https://www.ultraengine.com/community/topic/61340-createactor-causing-heap-corruption-when-used-on-a-camera/#comment-298637

I also added a -forcebuild flag that'll force the application to regenerate the files automatically. 

  • Thanks 1

Cyclone - Ultra Game System - Component PreprocessorTex2TGA - Darkness Awaits Template (Leadwerks)

If you like my work, consider supporting me on Patreon!

Link to comment
Share on other sites

Awesome, thank you! I still don't see how he was able to compile if his header and C++ file were incompatible, even if they were generated at different times. I have seen this happen with complicated partial builds when the compiler incorrectly links an object file with a mismatched header, but cleaning the project always solves those.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...