This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
Defold ist gut getestet und sollte unter normalen Umständen nur sehr selten abstürzen. Es lässt sich jedoch nicht garantieren, dass es niemals abstürzt, insbesondere wenn dein Spiel native Erweiterungen (native extensions) verwendet. Wenn du Probleme mit Abstürzen oder nativem Code hast, der sich nicht wie erwartet verhält, gibt es verschiedene Vorgehensweisen:
Am häufigsten wird der Code mit einem Debugger ausgeführt. Damit kannst du den Code schrittweise ausführen und Haltepunkte setzen. Bei einem Absturz hält der Debugger die Ausführung an.
Für jede Plattform gibt es mehrere Debugger.
Jedes Werkzeug kann bestimmte Plattformen debuggen:
Die einfachste Möglichkeit, deinen nativen Code zu debuggen, ist Debugging mit Protokollausgaben. Verwende die Funktionen im Namensraum dmLog, um Variablen zu beobachten oder den Ausführungsfluss sichtbar zu machen. Alle Protokollfunktionen geben Meldungen in der Ansicht Console im Editor und im Spielprotokoll aus.
Die Defold-Engine speichert bei einem schweren Absturz eine Datei namens _crash. Die Absturzdatei enthält Informationen über das System sowie über den Absturz. Die Ausgabe des Spielprotokolls gibt an, wo sich die Absturzdatei befindet (dies hängt vom Betriebssystem, dem Gerät und der Anwendung ab).
Du kannst das crash-Modul verwenden, um diese Datei in der nächsten Sitzung zu lesen. Es wird empfohlen, die Datei zu lesen, die Informationen zusammenzutragen, sie auf der Konsole auszugeben und an einen Analysedienst zu senden, der das Sammeln von Absturzprotokollen unterstützt.
Unter Windows wird außerdem eine Datei namens _crash.dmp erzeugt. Diese Datei ist beim Debuggen eines Absturzes hilfreich.
Wenn ein Absturz auf einem Mobilgerät auftritt, kannst du die Absturzdatei auf deinen eigenen Computer herunterladen und lokal auswerten.
Wenn die App debuggbar ist, kannst du das Absturzprotokoll mit dem Werkzeug Android Debug Bridge (ADB) und dem Befehl adb shell abrufen:
$ adb shell "run-as com.defold.example sh -c 'cat /data/data/com.defold.example/files/_crash'" > ./_crash
In iTunes kannst du den Container einer App anzeigen/herunterladen.
Im Fenster Xcode -> Devices kannst du auch die Absturzprotokolle auswählen
Wenn du einen Aufrufstapel (call stack) aus einer Datei namens _crash oder einer Protokolldatei erhältst, kannst du ihn symbolisieren. Dabei wird jede Adresse im Aufrufstapel in einen Dateinamen und eine Zeilennummer umgewandelt, was dabei hilft, die eigentliche Ursache zu finden.
Es ist wichtig, dass du die zum Aufrufstapel passende Engine verwendest. Andernfalls wirst du bei der Fehlersuche sehr wahrscheinlich an der falschen Stelle suchen! Verwende die Option --with-symbols, wenn du mit bob ein Bundle erstellst, oder aktiviere im Dialogfeld zur Bundle-Erstellung im Editor das Kontrollkästchen „Generate debug symbols“:
dmengine.dSYM.zip in build/arm64-ios enthält die Debug-Symbole für iOS-Builds.dmengine.dSYM.zip in build/x86_64-macos enthält die Debug-Symbole für macOS-Builds.projecttitle.apk.symbols/lib/ enthält die Debug-Symbole für die Zielarchitekturen.dmengine.pdb in build/x86_64-win32 enthält die Debug-Symbole für Windows-Builds.<project_name>_symbols neben dem HTML5-Bundle enthält <project_name>_wasm.js.symbols und, wenn die Architektur wasm_pthread-web ausgewählt ist, <project_name>_pthread_wasm.js.symbols.Es ist sehr wichtig, dass du die Debug-Symbole für jede öffentliche Veröffentlichung deines Spiels an einem geeigneten Ort speicherst und weißt, zu welcher Veröffentlichung sie gehören. Ohne die Debug-Symbole kannst du keine Abstürze in nativem Code debuggen! Außerdem solltest du eine unstripped-Version der Engine aufbewahren. Damit lässt sich der Aufrufstapel bestmöglich symbolisieren.
Du kannst die Debug-Symbole auf Google Play hochladen, damit alle in Google Play protokollierten Abstürze symbolisierte Aufrufstapel anzeigen. Packe den Inhalt des Ausgabeordners des Bundles projecttitle.apk.symbols/lib/ in ein ZIP-Archiv. Der Ordner enthält einen oder mehrere Unterordner mit Architekturnamen wie arm64-v8a, armeabi-v7a und x86_64.
$ ls <project>/build/<platform>/[lib]dmengine[.exe|.so]
$ unzip dmengine.apk -d dmengine_1_2_105
Ermittle die Adresse im Aufrufstapel
In einem nicht symbolisierten Aufrufstapel könnte sie beispielsweise so aussehen
#00 pc 00257224 libmy_game_name.so
Dabei ist 00257224 die Adresse
Löse die Adresse auf
$ arm-linux-androideabi-addr2line -C -f -e dmengine_1_2_105/lib/armeabi-v7a/libdmengine.so _address_
Hinweis: Wenn du einen Stacktrace aus den Android-Protokollen erhältst, kannst du ihn möglicherweise mit ndk-stack symbolisieren
--with-symbols an bob.jar) $ unzip <project>/build/arm64-darwin/build.zip
# it will produce a Contents/Resources/DWARF/dmengine
$ wget http://d.defold.com/archive/<sha1>/engine/arm64-darwin/dmengine.dSYM
Symbolisiere mit der Ladeadresse
Aus irgendeinem Grund funktioniert es nicht, nur die Adresse aus dem Aufrufstapel anzugeben (d. h. mit der Ladeadresse 0x0)
$ atos -arch arm64 -o Contents/Resources/DWARF/dmengine 0x1492c4
# Neither does specifying the load address directly
$ atos -arch arm64 -o MyApp.dSYM/Contents/Resources/DWARF/MyApp -l0x100000000 0x1492c4
Es funktioniert, wenn du die Ladeadresse zur Adresse addierst:
$ atos -arch arm64 -o MyApp.dSYM/Contents/Resources/DWARF/MyApp 0x1001492c4
dmCrash::OnCrash(int) (in MyApp) (backtrace_execinfo.cpp:27)