Opened 17 years ago

Closed 16 years ago

#3135 closed defect (fixed)

BASS: Crash when changing scalers during intro

Reported by: eriktorbjorn Owned by: fingolfin
Priority: high Component: Engine: Sky
Version: Keywords:
Cc: Game: Beneath a Steel Sky


BASS 0.0372 Current SVN snapshot (but also tested with 0.9.1)

It seems that if you change scaler (or, I guess, do anything else that forces the screen to redraw) during the BASS intro, there is a tiny chance that ScummVM will crash.

I managed to capture the crash in Valgrind, though since I had been making local changes to BASS at the time (touching screen.h, intro.cpp, sky.cpp and screen.cpp), the line number may be slightly off:

==24221== Thread 2: ==24221== Invalid read of size 1 ==24221== at 0x422F11D: (within /usr/lib/ ==24221== by 0x424B4A3: SDL_LowerBlit (in /usr/lib/ ==24221== by 0x424B6D3: SDL_UpperBlit (in /usr/lib/ ==24221== by 0x8089CA8: OSystem_SDL::internUpdateScreen() (graphics.cpp:678) ==24221== by 0x8088558: OSystem_SDL::updateScreen() (graphics.cpp:512) ==24221== by 0x4E36830: Sky::Screen::processSequence() (screen.cpp:516) ==24221== by 0x4E368DA: Sky::Screen::handleTimer() (screen.cpp:418) ==24221== by 0x4E37B8E: Sky::SkyEngine::gotTimerTick() (sky.cpp:510) ==24221== by 0x4E37BB2: Sky::SkyEngine::timerHandler(void*) (sky.cpp:505) ==24221== by 0x814F840: DefaultTimerManager::handler() (default-timer.cpp:107) ==24221== by 0x808C34A: timer_handler(unsigned, void*) (sdl.cpp:49) ==24221== by 0x422B30B: (within /usr/lib/ ==24221== Address 0x0 is not stack'd, malloc'd or (recently) free'd

Maybe it has to do with the animations being run by a timer, i.e. not the main thread? That sort of thing has haunted us in the past...

Ticket imported from: #1690813. Ticket imported from: bugs/3135.

Change History (4)

comment:1 by fingolfin, 17 years ago

Priority: normalhigh

comment:2 by fingolfin, 16 years ago

This is an odd one. I wonder whether it's really caused by a bug in the BASS code, though, or if it's not really a problem in the backend... ? Maybe the problem is triggered because a redraw is initiated from within a timer? Although at least in theory, a mutex should protect us from problems there.

The source code has shifted since you posted this, but looking at <>, it seems the offending line in the backend is this:

SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0);

so it crashed while trying to draw the OSD surface. Hu... could it be that in another thread, we are right in the middle of OSystem_SDL::displayMessageOnOSD(), which doesn't perform thread locking? If that's the case, maybe the following simple trick will help: Only change _osdAlpha at the very end of OSystem_SDL::displayMessageOnOSD(), to make sure the OSD won't be drawn before everything is fully setup.

comment:3 by fingolfin, 16 years ago

Owner: set to fingolfin
Resolution: fixed
Status: newclosed

comment:4 by fingolfin, 16 years ago

OK, found and fixed the problem. The displayMessageOnOSD() simply needs to lock the graphics mutex. Otherwise it might be called *while* updateScreen is blitting the OSD surface, which obviously can cause troubles.

Note: See TracTickets for help on using tickets.