Opened 4 months ago

Last modified 3 weeks ago

#16381 new defect

WAGE: Zhore's Xers crash when restarting game

Reported by: eriktorbjorn Owned by:
Priority: normal Component: Engine: Wage
Version: Keywords:
Cc: Game:

Description

Steps to reproduce:

  • Start the game Zhore's Xers. Use the Command menu to skip through the introduction messages.
  • From Beside Moat, go south. This will end the game.
  • Select New from the File menu. Use the Command menu to skip through the introduction messages.

This time, "Start Game" will crash ScummVM with the following assertion:

scummvm: backends/timer/default/default-timer.cpp:128: virtual bool DefaultTimerManager::installTimerProc(Common::TimerManager::TimerProc, int32, void*, const Common::String&): Assertion `interval > 0' failed.

Though it seems it doesn't always happen. I was able to capture this backtrace of it, however:

#0  __pthread_kill_implementation
    (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0)
    at ./nptl/pthread_kill.c:44
#1  0x00007ffff609e9ff in __pthread_kill_internal
    (threadid=<optimized out>, signo=6) at ./nptl/pthread_kill.c:89
#2  0x00007ffff6049cc2 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/posix/raise.c:26
#3  0x00007ffff60324ac in __GI_abort () at ./stdlib/abort.c:73
#4  0x00007ffff6032420 in __assert_fail_base
    (fmt=<optimized out>, assertion=<optimized out>, file=<optimized out>, line=128, function=<optimized out>) at ./assert/assert.c:118
#5  0x000055555cd5d401 in DefaultTimerManager::installTimerProc
    (this=0x5555612c41c0, callback=0x55555ca1996f <Wage::soundTimer(void*)>, interval=-37000, refCon=0x55556258dd40, id=...)
    at backends/timer/default/default-timer.cpp:128
#6  0x000055555ca19eda in Wage::soundTimer (refCon=0x55556258dd40)
    at engines/wage/sound.cpp:183
#7  0x000055555ca1a07b in Wage::WageEngine::updateSoundTimerForScene
    (this=0x55556145da20, scene=0x55556258dd40, firstTime=true)
    at engines/wage/sound.cpp:206
#8  0x000055555ca1cf43 in Wage::WageEngine::redrawScene (this=0x55556145da20)
    at engines/wage/wage.cpp:494
#9  0x000055555ca1ce85 in Wage::WageEngine::onMove
    (this=0x55556145da20, what=0x5555625886a0, from=0x555562e20090, to=0x55556258dd40) at engines/wage/wage.cpp:480
#10 0x000055555ca1fe17 in Wage::World::move
    (this=0x555562f62470, chr=0x5555625886a0, scene=0x55556258dd40, skipSort=false) at engines/wage/world.cpp:510
#11 0x000055555ca15bb5 in Wage::Script::compare
    (this=0x555562f6b3e0, o1=0x555563036f00, o2=0x5555630b5000, comparator=21)
    at engines/wage/script.cpp:883
#12 0x000055555ca15e97 in Wage::Script::evaluatePair
    (this=0x555562f6b3e0, lhs=0x555563036f00, op=0x555557f36f28 "M", rhs=0x555562fc4ec0) at engines/wage/script.cpp:914
#13 0x000055555ca16ca0 in Wage::Script::processMove (this=0x555562f6b3e0)
    at engines/wage/script.cpp:1088
#14 0x000055555ca12fd2 in Wage::Script::execute
    (this=0x555562f6b3e0, world=0x555562f62470, loopCount=1, inputText=0x7fffffffb660, inputClick=0x0) at engines/wage/script.cpp:224
#15 0x000055555ca1d168 in Wage::WageEngine::processTurnInternal
    (this=0x55556145da20, textInput=0x7fffffffb660, clickInput=0x0)
    at engines/wage/wage.cpp:523
#16 0x000055555ca1d537 in Wage::WageEngine::processTurn
    (this=0x55556145da20, textInput=0x55556304f320, clickInput=0x0)
    at engines/wage/wage.cpp:583
#17 0x000055555ca0c200 in Wage::Gui::executeMenuCommand
    (this=0x55556259e290, action=13, text=...) at engines/wage/gui.cpp:391
#18 0x000055555ca0bebe in Wage::menuCommandsCallback
    (action=13, text=..., data=0x55556259e290) at engines/wage/gui.cpp:319
#19 0x000055555d00a2a3 in Graphics::MacMenu::mouseRelease
    (this=0x555562f6ada0, x=151, y=28) at graphics/macgui/macmenu.cpp:1614
#20 0x000055555d008aca in Graphics::MacMenu::processEvent
    (this=0x555562f6ada0, event=...) at graphics/macgui/macmenu.cpp:1307
#21 0x000055555d02e747 in Graphics::MacWindowManager::processEvent
    (this=0x555562592fd0, event=...)
    at graphics/macgui/macwindowmanager.cpp:1094
#22 0x000055555ca0be88 in Wage::Gui::processEvent
    (this=0x55556259e290, event=...) at engines/wage/gui.cpp:313
#23 0x000055555ca1bced in Wage::WageEngine::processEvents (this=0x55556145da20)
    at engines/wage/wage.cpp:255
#24 0x000055555ca1b87a in Wage::WageEngine::run (this=0x55556145da20)
    at engines/wage/wage.cpp:185
#25 0x000055555814d41c in runGame
    (enginePlugin=0x55555fdfd4a0, system=..., game=..., meDescriptor=0x5555614287f0) at base/main.cpp:317
#26 0x000055555814f88a in scummvm_main (argc=1, argv=0x7fffffffe608)
    at base/main.cpp:803
#27 0x000055555814a322 in main (argc=1, argv=0x7fffffffe608)

Change History (2)

comment:1 by tag2015, 4 months ago

Component: --Unset--Engine: Wage

comment:2 by Bhumit-coder, 3 weeks ago

Hi, I investigated this issue and confirmed that the crash is caused by a negative interval being passed to installTimerProc() in the WAGE sound timer.

The interval is computed as:

nextRun - g_system->getMillis()

If the current system time exceeds nextRun, this results in a negative value, triggering the assertion (interval > 0).

I implemented a minimal fix by clamping the interval to a minimum value before scheduling the timer:

int interval = nextRun - g_system->getMillis();
if (interval <= 0)

interval = 1;

I have tested this locally and confirmed that it prevents the crash.

I would like to work on this issue and submit a patch. Please let me know if this approach is acceptable or if there are any preferred alternatives.

Note: See TracTickets for help on using tickets.