Process returned with status -805306369 (0xCFFFFFFF)

a marqué ce sujet comme résolu.

Bonjour, c’est encore moi ! :p

J’ai un problème avec mon programme, qui me retourne l’erreur que j’ai mis dans le titre. Pour résumer mon programme se lance, ne réponds pas et cesse de fonctionner. J’ai modifié quelques lignes que je soupçonnais être responsable du problème, et j’ai trouvé, mais je ne comprends pas pourquoi il y a ce problème. Je vous mets mon code et surligne les lignes incriminées :

Engine.h

#pragma once

#include <iostream>
#include <exception>
#include <stdexcept>
#include <SDL2/SDL.h>

//#include "ECS.h"
#include "Entity.h"
//#include "Component.h"
#include "Transform.h"
#include "RigidBody.h"
#include "UptrSdl2.h"
#include "EntityManager.h"
#include "SystemManager.h"

class Sprite;
class RenderSystem;
class TextureManager;

constexpr int SCREEN_WIDTH = 1280;
constexpr int SCREEN_HEIGHT = 720;
constexpr SDL_Color BLUE = {37,253,233,255};

class Engine {
    public:
        virtual ~Engine() = default;

        void quit();

        void events();
        void update();
        void render();

        bool isRunning() const;

        inline static Engine& get() {
            static Engine engine;
            return engine;
        }

        inline SDL_Renderer* getRenderer() {
            return renderer.get();
        }

        inline EntityManager& entities(){
            static EntityManager entities_;
            return entities_;
        }

        inline SystemManager& systems(){
            static SystemManager systems_;
            return systems_;
        }

    private:
        void init();
        Engine() {
            init();
        }

        bool running{false};
        sdl2::WindowPTR window{nullptr};
        sdl2::RendererPTR renderer{nullptr};
        SDL_Color clearColor;
};

Engine.cpp

#include "Engine.h"
#include "Sprite.h"
#include "RenderSystem.h"
#include "TextureManager.h"

void Engine::init() {
    if(SDL_Init(SDL_INIT_VIDEO) != 0) {
        std::string error = "In Engine (init #sdl): ";
        error += std::string{SDL_GetError()};
        std::cerr << error << std::endl;

        throw std::runtime_error(error);
    }

    auto winFlags = (SDL_WINDOW_RESIZABLE|SDL_WINDOW_ALLOW_HIGHDPI); //|SDL_WINDOW_MAXIMIZED
//    window = sdl2::WindowPTR{SDL_CreateWindow("Game Engine ECS",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,SCREEN_WIDTH,SCREEN_HEIGHT,winFlags)};
    window.reset(SDL_CreateWindow("Game Engine ECS",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,SCREEN_WIDTH,SCREEN_HEIGHT,winFlags));
    if(!window) {
        std::string error = "In Engine (init #window): ";
        error += std::string{SDL_GetError()};
        std::cerr << error << std::endl;

        throw std::runtime_error(error);
    }

    auto renderFlags = (SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);
//    renderer = sdl2::RendererPTR{SDL_CreateRenderer(window.get(),-1,renderFlags)};
    renderer.reset(SDL_CreateRenderer(window.get(),-1,renderFlags));
    if(!renderer) {
        std::string error="In Engine (init #renderer): ";
        error += std::string{SDL_GetError()};
        std::cerr << error << std::endl;

        throw std::runtime_error(error);
    }

    ///Création d'une entité test
    TextureManager::get().loadTexture("test","assets/test.png");

    Entity* e = new Entity();
    e->addComponent<Transform>();
    e->addComponent<RigidBody>();
    e->addComponent<Sprite>(renderer.get(),"test");
    entities().addEntity();

    clearColor = BLUE;
    running = true;
}

void Engine::quit() {
    running = false;
}

void Engine::events() {
    SDL_Event ev;
    while(SDL_PollEvent(&ev)) {
        switch(ev.type) {
            case SDL_QUIT:
                running = false;
                break;
            case SDL_KEYDOWN:
                running = false;
                break;
        }
    }
}

void Engine::update() {
    auto& entities = Engine::get().entities();
    auto& systems = Engine::get().systems();

    systems.update(entities);
}

void Engine::render() {
    SDL_SetRenderDrawColor(renderer.get(),BLUE.r,BLUE.g,BLUE.b,BLUE.a);
    SDL_RenderClear(renderer.get());

    auto& entities = Engine::get().entities();
    RenderSystem* rs = new RenderSystem();
    rs->update(entities);

    SDL_RenderPresent(renderer.get());
}

bool Engine::isRunning() const {
    return running;
}

TextureManager.h

#pragma once

#include <map>
#include <string>
#include <iostream>
#include <exception>
#include <stdexcept>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <SDL2/SDL_image.h>

#include "Engine.h"
#include "UptrSdl2.h"

class TextureManager {
    public:
        virtual ~TextureManager() = default;

        SDL_Texture* getTexture(std::string id);
        void loadTexture(std::string id, std::string path);

        TTF_Font* getFont(std::string id);
        void loadFont(std::string id, std::string path,int fontsize);

        inline static TextureManager& get() {
            static TextureManager tm;
            return tm;
        }

    private:
        void init();
        TextureManager() {
            init();
        }

        std::map<std::string,sdl2::FontPTR> fonts;
        std::map<std::string,sdl2::TexturePTR> textures;
};

TextureManager.cpp

#include "TextureManager.h"

SDL_Texture* TextureManager::getTexture(std::string id) {
    if(textures.count(id) > 0) {
        return textures.at(id).get();
    }
    return nullptr;
}

void TextureManager::loadTexture(std::string id, std::string path) {
    if(textures.count(id) <= 0) {
        SDL_Texture* newText = IMG_LoadTexture(Engine::get().getRenderer(),path.c_str());
        sdl2::TexturePTR newTexture{newText};
//        sdl2::TexturePTR newTexture = sdl2::TexturePTR{IMG_LoadTexture(Engine::get().getRenderer(),path.c_str())};
        if(newTexture != nullptr) {
//            textures[id] = newTexture;
            textures.emplace(id,std::move(newTexture));

            std::string log = "In TextureManager (loadTexture): ";
            log += std::string{"Texture (" + path + ") loaded."};
            std::cout << log << std::endl;
        } else {
            std::string error = "In TextureManager (loadTexture): ";
            error += std::string{IMG_GetError()};
            std::cerr << error << std::endl;

            throw std::runtime_error(error);
        }
    }
}

TTF_Font* TextureManager::getFont(std::string id) {
    return (fonts.count(id) > 0 ? fonts[id].get() : nullptr);
}

void TextureManager::loadFont(std::string id, std::string path, int fontsize) {
    if(fonts.count(id) <= 0) {
        TTF_Font* newF = TTF_OpenFont(path.c_str(),fontsize);
        sdl2::FontPTR newFont{newF};
        if(newFont != nullptr) {
//            fonts[id] = newFont;
            fonts.emplace(id,std::move(newFont));

            std::string log = "In TextureManager (loadFont): ";
            log += std::string{"Font (" + path + ") loaded."};
            std::cout << log << std::endl;
        } else {
            std::string error = "In TextureManager (loadFont): ";
            error += std::string{TTF_GetError()};
            std::cerr << error << std::endl;

            throw std::runtime_error(error);
        }
    }
}

void TextureManager::init() {
    if(TTF_Init() != 0) {
        std::string error = "In TextureManager (init #ttf): ";
        error += std::string{TTF_GetError()};
        std::cerr << error << std::endl;

        throw std::runtime_error(error);
    }

    auto imgFlags = IMG_INIT_JPG|IMG_INIT_PNG;
    auto initted = IMG_Init(imgFlags);
    if((initted&imgFlags) != imgFlags) {
        std::string error = "In TextureManager (init #img): ";
        error += std::string{IMG_GetError()};
        std::cerr << error << std::endl;

        throw std::runtime_error(error);
    }
}

Je rajoute également mon namespace sdl2 :

UptrSdl2.h

#pragma once

#include <memory>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_mixer.h>

namespace sdl2 {
    struct SDL_Deleter {
        void operator()(SDL_Window*     ptr) {if(ptr) SDL_DestroyWindow(ptr);}
        void operator()(SDL_Renderer*   ptr) {if(ptr) SDL_DestroyRenderer(ptr);}
        void operator()(SDL_Surface*    ptr) {if(ptr) SDL_FreeSurface(ptr);}
        void operator()(SDL_Texture*    ptr) {if(ptr) SDL_DestroyTexture(ptr);}
        void operator()(SDL_RWops*      ptr) {if(ptr) SDL_RWclose(ptr);}
        void operator()(SDL_Joystick*   ptr) {if(ptr) SDL_JoystickClose(ptr);}
        void operator()(TTF_Font*       ptr) {if(ptr) TTF_CloseFont(ptr);}
        void operator()(Mix_Chunk*      ptr) {if(ptr) Mix_FreeChunk(ptr);}
        void operator()(Mix_Music*      ptr) {if(ptr) Mix_FreeMusic(ptr);}
        void operator()(SDL_Haptic*     ptr) {if(ptr) SDL_HapticClose(ptr);}
    };
    using WindowPTR     = std::unique_ptr<SDL_Window,   SDL_Deleter>;
    using RendererPTR   = std::unique_ptr<SDL_Renderer, SDL_Deleter>;
    using SurfacePTR    = std::unique_ptr<SDL_Surface,  SDL_Deleter>;
    using TexturePTR    = std::unique_ptr<SDL_Texture,  SDL_Deleter>;
    using RWopsPTR      = std::unique_ptr<SDL_RWops,    SDL_Deleter>;
    using JoystickPTR   = std::unique_ptr<SDL_Joystick, SDL_Deleter>;
    using FontPTR       = std::unique_ptr<TTF_Font,     SDL_Deleter>;
    using Mix_ChunkPTR  = std::unique_ptr<Mix_Chunk,    SDL_Deleter>;
    using Mix_MusicPTR  = std::unique_ptr<Mix_Music,    SDL_Deleter>;
    using HapticPTR     = std::unique_ptr<SDL_Haptic,   SDL_Deleter>;
}

Est-ce que quelqu’un peut m’aider ? Je peux passer l’entièreté de mon projet si besoin :p Merci d’avance pour votre aide, j’ai beau me creuser les méninges avec ce soucis j’ai aucune idée de ce qui pourrait être la cause de ce problème…

+0 -0

Salut,

Je vois que tu as mis des lignes de log pour trouver d’où vient le problème, tu devrais plutôt utiliser un débogueur, par exemple gdb. Ce n’est pas difficile à utiliser, en quelques mots :

  • compile avec l’option -g pour activer les symboles de débogage
  • lance ton binaire comme ceci : gdb machin.exe
  • cela amène dans la console interactive du débogueur
  • pour lancer le programme : run
  • quand le programme plante, afficher la backtrace: backtrace
  • pour quitter : Ctrl+D

Cela te permet d’identifier où le programme s’est arrêté sans modifier ton code. Le débogueur te permet également de placer des points d’arrêt, d’afficher le contenu de la mémoire, etc. Cela demande un peu d’apprentissage, mais c’est un outil très efficace que je ne peux que te conseiller.

Cela mis à part, peux-tu donner la sortie de ton programme ? Arrive-t-il jusqu’à cette ligne ?

throw std::runtime_error(error);

Si oui, n’est-ce pas la raison de l’arrêt ? Une exception est levée et n’est pas capturée, donc le programme s’arrête ?

Bonne soirée.

Comment je compile avec l’option -g et comment je lance mon binaire (?) avec gdb ? J’utilise Code::Blocks c’est pas moi qui gère ça ^^'


EDIT : J’ai vu comment lancer le débuggueur sur Code::Blocks, je comprends pas comment ça marche : pour pouvoir entrer des trucs dans commands, je suis obligé de cliquer sur "break debugger", et après quand j’ai fait backtrace j’ai eu ça :

> backtrace
#0  0x00007ffb27790861 in ntdll!DbgBreakPoint () from C:\WINDOWS\SYSTEM32\ntdll.dll
#1  0x00007ffb277bc98e in ntdll!DbgUiRemoteBreakin () from C:\WINDOWS\SYSTEM32\ntdll.dll
#2  0x00007ffb261c7034 in KERNEL32!BaseThreadInitThunk () from C:\WINDOWS\System32\kernel32.dll
#3  0x00007ffb27742651 in ntdll!RtlUserThreadStart () from C:\WINDOWS\SYSTEM32\ntdll.dll
#4  0x0000000000000000 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

Le programme bug à cause de la méthode loadTexture, c’est certain parce que quand je supprime la ligne où j’appelle loadTexture mon programme n’a pas de soucis, mais il ne me renvoie pas l’erreur que j’ai écrit pour le runtime_error, donc je pense pas que ça soit ça le problème

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte