(solved) Crash on restoring game

Started by Radiant, Tue 17/09/2013 14:20:47

Previous topic - Next topic

Radiant

On restoring a saved game, I got the following crash dump: http://crystalshard.net/test/CrashInfo.3.21.1115.dmp

An exception 0xC0000005 occurred in ACWIN.EXE at EIP = 0x00425435 ; program pointer is +6, ACI version 3.21.1115, gtags (9,4)
AGS cannot continue, this exception was fatal. Please note down the numbers above, remember what you were doing at the time and post the details on the AGS Technical Forum.
in "GlobalScript.asc", line 2812
An error file CrashInfo.dmp has been created. You may be asked to upload this file when reporting this problem on the AGS Forums. (code 0)

Restoring the game triggers the on_event(eEventRestoreGame) function, which does
Code: ags

    if (IsSpeechVoxAvailable ()) gui[CONTROLS].Controls[16].AsSlider.Max = 255;
    else                         gui[CONTROLS].Controls[16].AsSlider.Max = 0;
    GUIOff           (SAVEGAME);
    GUIOff           (CONTROLS);
    if (here > 2)
      SetCursorMode  (eModeWalkto);
    else ReadRecords ();
    SetDefaultCursor ();
    SeekMP3PosMillis (0);
    i = player.inv[CurseRing];
    WriteRecords     (0);
    if (i == 0 && player.inv[CurseRing]) invwarn = 2;
    overlay = 0;


Crimson Wizard

Hmm, which line is line #2812?

Radiant

Unfortunately I'm not sure, as I made some changes between sending out this build and receiving the bug report. I would expect it to be something like SetMp3PosMillis while the MP3 isn't playing yet.

Radiant

Might it be possible to determine from the .dmp file or the EIP value which function it is? I can't really imagine SetCursorMode() or SetDefaultCursor() or IsSpeechAvailable() crashing on anything, and if the error was in my own function ReadRecords() then I would have gotten a line number from within that module. So that means the issue is either in SeekMP3PosMillis() or the gui[CONTROLS].Controls[16].AsSlider.Max assignment. Would it help if I sent you the EXE and saved game?

Crimson Wizard

#4
EIP and crash dump are unusable for me, because they could be used exclusively with original 3.2.1 code & debug files created by CJ (crash dump must match engine's timestamp).

"program pointer = 6" does not tell much either, it means that the engine went into updating events (processing on_event function).
"gtags" are ids of the last updated gui and gui control, although it is impossible to tell if these guis are currently updated, or were updated some time in the past.

I can check EXE under debugger of course. Does it reproduce all the time?

Radiant

Yes, it reproduces reliably. I will send you an e-mail with links to the executables, I suppose the e-mail link in your profile is good for that? Thank you for your help!

Crimson Wizard

#6
I got your game, and I see that it is SeekMP3PosMillis(0) that causes this.
This is a bit complicated, and I think that's actually a bug introduced when new Audio system was created (in 3.2).


//--------------------------------------------
EDIT: just to clarify, what you sent me is all the files that you actually run the game with? The crash is related to missing VOX file.
Have you saved these games with the VOX and tried to restore without one?
//--------------------------------------------


Thing is that saved game remembers a currently playing music, and tries to start it on load. But there's no VOX, so it can't play.
At the same time, there's a certain internal value, that tells engine that the music track of certain type WAS present at the time of saving the game. Although sound clip is missing, this value is not reset.
When SeekMP3PosMillis() is called, engine checks that value, and thinks that there's a music track of certain format playing, but does not actually check if anything is loaded in the audio channel. So it then tries to work with non-existing channel, and crashes due accessing invalid memory.

How to deal with it? Normally, this should be fixed in the engine (which I might do).
Meanwhile, add IsMusicPlaying() check before SeekMP3PosMillis() call. Thankfully, IsMusicPlaying() makes sufficient checks and recognizes when the music is not loaded; it also resets the aforementioned value, so any subsequent music-related functions will work correctly.

Actually you may just write:
Code: ags

IsMusicPlaying();
SeekMP3PosMillis (0);

Yes, without even "if" condition, because, as I said, it will bring game state to consistency simply by being called. :)

Radiant

Yes, there is a music.vox file; that should have been in the archive I sent you, but looks like I forgot it. Sorry.

Thanks for your help!

Crimson Wizard

#8
Quote from: Radiant on Sun 22/09/2013 10:45:29
Yes, there is a music.vox file; that should have been in the archive I sent you, but looks like I forgot it. Sorry.
Err, but in this case the problem might be different.

E: Okay, I put some dummy audio files with matching names in the game folder, and the saves loaded well. So it was because of the missing VOX from the very beginning?

PS. The game's gorgeous! Good luck finishing it :)

SMF spam blocked by CleanTalk