TheCherno / Sparky

Cross-Platform High Performance 2D/3D game engine for people like me who like to write code.
Apache License 2.0
1.09k stars 222 forks source link

Crashing on Debug build of external app using Release build of Sparky at String #134

Open 3x3y3z3t opened 6 years ago

3x3y3z3t commented 6 years ago

I've setup the environment as following: I build Sparky in Release. After that I copy all the .lib (and .pdb file for debug) to another lib folder. I also copy all the .h file and default shader file to another include folder (I do keep the folder structure). The two include and lib folder is now the Sparky library seperated from the source code. I create a new project and set the include path and lib path to those include and lib folder, set lib name in Linker>Input, and copy the following Preprocessor from Sandbox that I think they are actually important

SP_PLATFORM_WINDOWS
WIN32
_CRT_NONSTDC_NO_DEPRECATE
_CRT_SECURE_NO_WARNINGS
_MBCS

to the new project, same for both Debug and Release. I also put the necessary dll in the same folder as .exe file.

The new project, called TestGame, built successfully in Debug and Release. When I try running in Debug. I got a crash (Access violation to 0x00000000 in memset.asm). Tracing back the stack let me known that in sp::Application's constructor, the string for name passed in was null. I've tried the following:

// class Game;
public:
    String gn = "aaaaa";
    Game()
        : sp::Application(gn, { 1280, 720, false, false }, sp::graphics::API::RenderAPI::OPENGL)
    {}

and when debugging, gn appeared to be null. What confused me was when I switch to Release, this TestGame project run normally.

I doubt the problem is my fault, but I have tried created another fresh project and it remain the same. I don't know if anyone also encounter this problem, or using Sparky as library like me, but please give it a try and help me in this. I can continue using only Release mode, but that will be pretty annoying if I need to debug some part of my app.

TheCherno commented 6 years ago

Actually, this has nothing to do with Sparky and is in fact your fault (sorry 😉). The reason this is happening is because the super class constructor (Application) is being called before your string is being initialized; so you're passing an uninitialized string to the Application constructor which is what's causing the crash.

You can solve this by either just passing in your application name directly into the constructor, creating a static/global application name, or by taking in the application name string as a parameter into your Game constructor.

3x3y3z3t commented 6 years ago

I have Google here and there and they said that containers like std::string should corrupt its contained data when passing through DLL boundaries. I then done some workaround by creating another version of Application constructor that takes in const char* instead of std::string, and it work perfectly, no crash anymore. So can I say the fault is also not on me but because of std::string is being hillarious?

By changing the parameter type from std::string to const char* (or char*), I think I have (temporarily) solved this problem. If you think the solution is okay, feel free to close the issue.