#4004 closed defect (fixed)
GUI: Crash in GMM when changing scale factor
Reported by: | fingolfin | Owned by: | fingolfin |
---|---|---|---|
Priority: | high | Component: | GUI |
Version: | Keywords: | ||
Cc: | Game: |
Description
Today, I noticed that I could sometimes trigger a weird crash in latest SVN. It seems to be a bug in either the GUI or the RTL / GMM code. I still have no good way to trigger it, but will try to find one when I have more time. Here is what I did: Started a game (in this case, DOTT in the SCUMM engine), opened the GMM menu via F6. Then I changed the scaler from 1x to 2x and back, and it suddenly crashed. This happened a few times to me now, though I have still not figured out when exactly it happens, and it is a bit harder to try for long due to another bug I am about to report... :)
Here is a partial backtrace:
Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0xc000000f 0x006989e3 in GUI::Dialog::handleMouseMoved (this=0x111fd40, x=-33, y=216, button=0) at gui/dialog.cpp:257 257 int wx = w->getAbsX() - _x; (gdb) bt #0 0x006989e3 in GUI::Dialog::handleMouseMoved (this=0x111fd40, x=-33, y=216, button=0) at gui/dialog.cpp:257 #1 0x006acaa4 in GUI::NewGui::runLoop (this=0x1866600) at gui/newgui.cpp:262 #2 0x00699179 in GUI::Dialog::runModal (this=0x111fd40) at gui/dialog.cpp:73 #3 0x000c548b in Scumm::ScummEngine::runDialog (this=0x165db000, dialog=@0x111fd40) at engines/scumm/scumm.cpp:2277 #4 0x00777013 in Engine::openMainMenuDialog (this=0x165db000) at engines/engine.cpp:234 #5 0x0077afad in DefaultEventManager::pollEvent (this=0x117c710, event=@0xbfffd828) at backends/events/default/default-events.cpp:419 #6 0x0006d7b2 in Scumm::ScummEngine::parseEvents (this=0x165db000) at engines/scumm/input.cpp:62 #7 0x000c44e0 in Scumm::ScummEngine::waitForTimer (this=0x165db000, msec_delay=100) at engines/scumm/scumm.cpp:1781 #8 0x000c480a in Scumm::ScummEngine::go (this=0x165db000) at engines/scumm/scumm.cpp:1749 #9 0x0000bbac in runGame (plugin=0x1146000, system=@0x1828000, edebuglevels=@0xbfffe154) at base/main.cpp:216 #10 0x0000c494 in scummvm_main (argc=1, argv=0x11099f0) at base/main.cpp:309
The odd thing is that I am not quite sure why it crashes exactly there; maybe the trace is just wrong, but FYI:
(gdb) p this $5 = (class GUI::Dialog * const) 0x111fd40 (gdb) p w $6 = (class GUI::Widget *) 0x17cb4ad0
So neither w nor "this" are zero. Maybe the vtable got corrupt, but I have no idea how to print that. Some more data:
(gdb) p *w $11 = { <GUI::GuiObject> = { <GUI::CommandReceiver> = { _vptr$CommandReceiver = 0xc0000003 }, members of GUI::GuiObject: _x = 3, _y = -16384, _w = 7, _h = 12, _name = { static _builtinCapacity = 24, _size = 16, _str = 0x17cb4ae4 "GlobalMenu.Title", { _storage = "GlobalMenu.Title\000\000\000\000??\032\001", _extern = { _refCount = 0x626f6c47, _capacity = 1699572833 } }, static emptyString = { static _builtinCapacity = 24, _size = 0, _str = 0x957388 "", { _storage = '\0' <repeats 23 times>, _extern = { _refCount = 0x0, _capacity = 0 } }, static emptyString = <same as static member of an already seen type> } }, _firstWidget = 0x0 }, members of GUI::Widget: _type = 1413830740, _boss = 0x111fd40, _next = 0x0, _id = 0, _hasFocus = true, _state = GUI::Theme::kStateEnabled, _flags = 1 }
(gdb) p *this $12 = (MainMenuDialog) { <GlobalDialog> = { <GUI::Dialog> = { <GUI::GuiObject> = { <GUI::CommandReceiver> = { _vptr$CommandReceiver = 0x8edce8 }, members of GUI::GuiObject: _x = 199, _y = 110, _w = 242, _h = 260, _name = { static _builtinCapacity = 24, _size = 10, _str = 0x111fd54 "GlobalMenu", { _storage = "GlobalMenu\000\001", '\0' <repeats 11 times>, _extern = { _refCount = 0x626f6c47, _capacity = 1699572833 } }, static emptyString = { static _builtinCapacity = 24, _size = 0, _str = 0x957388 "", { _storage = '\0' <repeats 23 times>, _extern = { _refCount = 0x0, _capacity = 0 } }, static emptyString = <same as static member of an already seen type> } }, _firstWidget = 0x11a4e00 }, members of GUI::Dialog: _mouseWidget = 0x0, _focusedWidget = 0x17cb4ad0, _dragWidget = 0x0, _visible = true, _backgroundType = GUI::Theme::kDialogBackgroundSpecial, _result = 0 }, <No data fields>}, members of MainMenuDialog: _engine = 0x165db000, _logo = 0x11a4e00, _rtlButton = 0x17ca8d70, _aboutDialog = 0x17ca8e70, _optionsDialog = 0x17cad600 }
Ticket imported from: #2210082. Ticket imported from: bugs/4004.
Change History (7)
comment:1 by , 16 years ago
Summary: | GUI: → GUI: Crash in GMM when changing scale factor |
---|
comment:2 by , 16 years ago
comment:3 by , 16 years ago
BTW, I noticed that the modern theme only define GlobalMenu.Title in the 320x mode, when the logo is hidden. But if DISABLE_FANCY_THEMES is set, it will try to access this variable in all cases and resolutions.
comment:4 by , 16 years ago
I've been looking into it and I'm certainly as puzzled as you are. I obviously haven't been able to reproduce the crash. Only trying on Win32 though, because I'm gonna need MSVS's jit debugger to hunt that down.
Have you had any luck, Max?
comment:5 by , 16 years ago
Owner: | set to |
---|---|
Resolution: | → fixed |
Status: | new → closed |
comment:6 by , 16 years ago
The cause of this bug was a subtle yet nasty bug in ThemeLayout and its makeClone method, which cloned ThemeLayout objects imperfectly: It did clone them but did not update the _parent members of the clones, which hence still pointed to the original parent -- not the new parent. This works fine as long as the both clone and original (resp. their parents) stay in memory; but if the original ThemeLayout's parent gets deleted, obviously problems are likely to crop up -- problems just like the one I reported here.
Anyway, I commited a fix for this to SVN (rev 35546).
comment:7 by , 6 years ago
Component: | → GUI |
---|
Actually, looking at it again, it is clear that the virtual table of object "w" has been smashed, as is made obvious by the line _vptr$CommandReceiver = 0xc0000003 from my dump. Here, "w" is the widget "GlobalMenu.Title" of the dialog "GlobalMenu". At the time of crash, it happend to be the _focusedWidget, too. Maybe that knowledge will help to reproduce the crash. And/or to figure out where we overwrite memory.