2017-06-03 3 views
2

Ich habe Probleme mit einem Spiel, an dem ich gearbeitet habe, wo ich, nachdem ich Musik hinzugefügt habe, Segfaulting in meinem häufig aufgerufenen Texture-loading Code zwischen 5-30 Sekunden nach dem Start gestartet habe . Das Beste, was mir einfiel, war, dass es sich um eine Art von Speicherkorruption handelt. Nach einer guten Woche, in der ich erfolglos versuchte, es zu debuggen (Dinge wie GFlags pageheap auszuprobieren), schaffte ich es, es auf den folgenden Code zu reduzieren, der immer noch das Problem aufweist.Mix_PlayMusic verursacht Speicherbeschädigung

Manchmal segfold dieses Segment mit dem Callstack, der SDL2_mixer.dll durchläuft, aber meist tritt es in dem SDL_CreateTextureFromSurface Aufruf auf, da der Renderer in einem fehlerhaften Zustand ist. numTextures wird auf meinem Rechner zwischen 15000-40000 (Windows 10 x64, mit Programm für x86 kompiliert).

Mein Bauchgefühl sagt mir, dass es ein Problem in meiner Umgebung oder Code, aber kein Problem in SDL selbst, aber ich bin ratlos. Jede Hilfe oder Einsichten würde sehr geschätzt werden.

#include <SDL_image.h> 
#include <SDL_mixer.h> 
#include <cassert> 

int main(int argc, char* argv[]) 
{ 
    assert(SDL_Init(SDL_INIT_EVERYTHING) == 0); 

    SDL_Window * pWindow_ = SDL_CreateWindow(
     "", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0x0); 
    assert(pWindow_ != nullptr); 

    SDL_Renderer * pRenderer_ = SDL_CreateRenderer(pWindow_, -1, 0); 
    assert(pRenderer_ != nullptr); 

    assert(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 512) == 0); 

    Mix_Music * pMusic = Mix_LoadMUS("sounds/tranquility.wav"); 
    assert(pMusic != nullptr); 
    assert(Mix_PlayMusic(pMusic, -1) == 0); 

    SDL_Surface * pSurface = IMG_Load("images/caution.png"); 
    assert(pSurface != nullptr); 
    SDL_Texture * pTexture = SDL_CreateTextureFromSurface(pRenderer_, pSurface); 
    assert(pTexture != nullptr); 

    int numTextures = 0; 
    while (true) 
    { 
     numTextures += 10; 
     assert(pTexture != nullptr); 
     SDL_DestroyTexture(pTexture); 
     pTexture = SDL_CreateTextureFromSurface(pRenderer_, pSurface); 
     assert(pTexture != nullptr); 
    } 
} 
+2

Haben Sie überprüft, dass 'Mix_LoadMUS()' ein nicht-NULL 'Mix_Music *' zurückgibt? Die ['Mix_PlayMusic()' docs] (https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC57) sagt nichts darüber aus, wie man NULL 'music' Argumente vernünftig behandeln kann. Dito für Ihren 'IMG_Load()' Anruf. – genpfault

+0

@genpfault gutes Denken. Ich habe Null-Prüfungen für pTexture vor dem Zerstören und nach dem Erstellen und in Mix_LoadMUS hinzugefügt. Ich habe auch in Mix_PlayMusic für null behauptet. Keine dieser Behauptungen versagt. Und es ist erwähnenswert, dass bis zum Absturz die Musik wie erwartet abgespielt wird. –

+1

Hervorragend, vielen Dank für die doppelte Überprüfung und Aktualisierung des MCVE! Als nächstes: hast du SDL2, SDL_mixer, & SDL_image mit deinem Compiler deiner Wahl gebaut (ich vermute ein Visual Studio der letzten Zeit?) Oder benutzt du die Binaries von libsdl.org? Wenn Sie die Binärdateien verwenden, versuchen Sie, sie lokal im Debug- oder RelWithDebInfo-Modus zu erstellen, damit Ihre Rückverfolgungsfunktionen verständlicher werden. Eine andere Sache, die Sie ausprobieren sollten, ist das Hinzufügen eines 'SDL_PumpEvents()' zu Ihrer 'while' Schleife. Sorry, ich habe nichts besseres, was Sie haben, sieht OK für mich aus :( – genpfault

Antwort

1

Die Lösung bestand darin, auf die neueste Version von SDL (2.0.3 -> 2.0.5) zu aktualisieren.

Ich begann mit der Entwicklung des fraglichen Projekts mit einer Engine-Code-Basis, die ich vor etwa 2 Jahren von SDL 1.2 auf 2.0 aktualisiert habe, als die neueste Version 2.0.3 war.

Als ich vor kurzem Sound und Musik hinzugefügt habe, nahm ich die neuesten SDL_mixer, und dachte nicht, SDL auf die neueste 2.0.5 zu aktualisieren.

Nach dem Abrufen der neuesten Entwicklungs- und Laufzeitbibliotheken für SDL (und SDL_image und SDL_mixer für ein gutes Maß), verschwand das Problem.

Ich bin nicht ganz damit zufrieden. Ich bin ziemlich überrascht, dass die neuere SDL_mixer erfolgreich mit einem älteren SDL verlinkt, wenn sie nicht kompatibel waren. Außerdem kann ich online keine Ressourcen finden, die auf Kompatibilitätsprobleme hinweisen. Daher habe ich ein unbehagliches Gefühl, dass vielleicht etwas anderes passiert ist, was übrigens durch das Upgrade gelöst wurde.

Verwandte Themen