Hi,
I recently tried to run the MS-Windows WWII strategy game "Hearts of Iron" using Wine on Linux. And it *very nearly* works. In fact, it's so close I'm trying to debug the problem in the hope of getting it working. I hope that someone here can give me a few wine debugging tips.
Actually, the game runs perfectly - absolutely "gold" standard. I gave it a 5-hour "stress test" ;-) and did not experience a single problem. There are some minor problems on startup, but there are reasonable workarounds for those.
The problem, though, is that saved games cannot be loaded. Unfortunately, this is a show-stopper as a game of HoI typically takes several days to play! Fortunately the problem is 100% repeatable.
FYI: I'm running Debian Sarge on x86, no native windows partition. I first tried the latest debian wine package, and then rebuilt from CVS HEAD code of Fri 13 August (possibly a bad day to choose :-). Exactly the same behaviour occurred.
Info on the game can be found here: http://www.heartsofiron-game.com/. It's a WWII strategy game with pleasant but not intensive graphics.
When running "wine HoI.exe" and trying to load a saved game, a message is output: wine: Unhandled exception (thread 0009), starting debugger.. Usage: winedbg [--auto] [--gdb] comdline There is then no response to the keyboard; no debugger prompt or anything. Is this meant to start a debugger interactive session here, or am I supposed to somehow start a debugger and point it at the wine process? If so, info on how to do so would be appreciated.
I ran "winedbg HoI.exe" and got exactly the same behaviour, though with a bit more info: <output> First chance exception: page fault on read access to 0x00000006 in 32-bit code (0x004191fb). Register dump: CS:0073 SS:007b DS:007b ES:007b FS:003b GS:0033 EIP:004191fb ESP:406bf4ec EBP:406bfe94 EFLAGS:00210206( - 00 - RIP1) EAX:48258e60 EBX:00000000 ECX:00000000 EDX:007e5f44 ESI:418736c0 EDI:45ae16e3 Stack dump: 0x00000000: 00000000 00000000 00000000 00000000 0x00000010: 00000000 00000000 00000000 00000000 0x00000020: 00000000 00000000 00000000 00000000 0x00000030: 00000000 00000000 00000000 00000000 0x00000040: 00000000 00000000 00000000 00000000 0x00000050: 00000000 00000000 00000000 00000000 0x00000060:
Backtrace: =>1 0x004191fb (0x406bfe94) 2 0x005af5b2 (0x406bff20) 3 0x404ff9f2 start_process+0xf2(arg=0x0) [process.c:995] in kernel32 (0x406bfff4) 4 0x4002c151 wine_switch_to_stack+0x11 in libwine.so.1 (0x00000000) 0x004191fb: movl 0x6(%ecx),%ecx Wine-dbg> </output>
Qn: is there any way of getting function names in that backtrace rather than just addresses? I've tried "CFLAGS=-g ./configure" when rebuilding wine, but haven't had time to test the resulting wine binaries.
And then is there a way to step through at the source rather than assembly level?
It's apparent here that %ecx is null when not expected to be, resulting in a bad access to memory address 0x00000006.
I also tried the "WINEDEBUG=+relay" option as recommended in the wine docs. However after leaving the program running overnight, and having generated 3 gigabytes of log output, the point where the bug occurs hadn't been reached. I think that what's happening is that there is a thread (0011) which is driven by timer ticks [probably doing GUI or sound stuff], and that because HoI is running much more slowly under +relay, that the thread doing the load-game work (0009) isn't actually getting any CPU time at all. NB: the log was only 3GB because I used grep to discard output about RtlEnterCriticalSection and RtlLeaveCriticalSection. Without that, the log would be closer to 30GB!
Any suggestions on how to make progress on this issue are welcome. Pointers to documentation on debugging this sort of thing are very welcome.
By the way, I'm an experienced c/c++ developer on unix/linux, but know very little about Windows programming (and frankly would prefer to leave it that way :-). It's been a while since I've used gdb and friends, but can brush up on that if it's useful.
Cheers,
Simon
PS: Congrats to the Wine team. I was most impressed how well HoI ran on wine.
Simon Kitching wrote:
There is then no response to the keyboard; no debugger prompt or anything. Is this meant to start a debugger interactive session here, or
--- snip ---
Backtrace: =>1 0x004191fb (0x406bfe94) 2 0x005af5b2 (0x406bff20) 3 0x404ff9f2 start_process+0xf2(arg=0x0) [process.c:995] in kernel32 (0x406bfff4) 4 0x4002c151 wine_switch_to_stack+0x11 in libwine.so.1 (0x00000000) 0x004191fb: movl 0x6(%ecx),%ecx Wine-dbg>
This ^^^^^ here is the debugger prompt.
</output>
Qn: is there any way of getting function names in that backtrace rather than just addresses? I've tried "CFLAGS=-g ./configure" when rebuilding wine, but haven't had time to test the resulting wine binaries.
Yes, recompile wine with debugging enabled. I think it is a ./configure option but it comes down to adding -g to the gcc options.
And then is there a way to step through at the source rather than assembly level?
Same as above.
I also tried the "WINEDEBUG=+relay" option as recommended in the wine
--- snip---
sound stuff], and that because HoI is running much more slowly under +relay, that the thread doing the load-game work (0009) isn't actually getting any CPU time at all. NB: the log was only 3GB because I used
Yes, the observer changes the nature of the observed. I absolutely hate that. But the fact that it happens sometimes points to some kind of race condition that no longer occurs when it is slowed down somewhat, this is at least true when you're programming at the hardware level :-)
By the way, I'm an experienced c/c++ developer on unix/linux, but know very little about Windows programming (and frankly would prefer to leave it that way :-). It's been a while since I've used gdb and friends, but can brush up on that if it's useful.
You and me both. Actually, I wasn't even much of a C++ coder until someone at work told me to make an app work on wine, which is how I landed on this list. And then, shortly afterwards, I was thrown into Symbian c++ development :-) Talk about being thrown in on the deep end.
PS: Congrats to the Wine team. I was most impressed how well HoI ran on wine.
Sounds almost too good to be true, I must admit :-)
Cheers, Izak
Hi,
On Thu, Aug 19, 2004 at 06:43:14PM +1200, Simon Kitching wrote:
Backtrace: =>1 0x004191fb (0x406bfe94) 2 0x005af5b2 (0x406bff20)
All in app space, most likely. Not very useful, I'm afraid.
And then is there a way to step through at the source rather than assembly level?
--> only if you have the game source ;-)
It's apparent here that %ecx is null when not expected to be, resulting in a bad access to memory address 0x00000006.
Yup, most likely.
I also tried the "WINEDEBUG=+relay" option as recommended in the wine docs. However after leaving the program running overnight, and having generated 3 gigabytes of log output, the point where the bug occurs hadn't been reached. I think that what's happening is that there is a thread (0011) which is driven by timer ticks [probably doing GUI or sound stuff], and that because HoI is running much more slowly under +relay, that the thread doing the load-game work (0009) isn't actually getting any CPU time at all. NB: the log was only 3GB because I used grep to discard output about RtlEnterCriticalSection and RtlLeaveCriticalSection. Without that, the log would be closer to 30GB!
You should at least have used pipes as described in the User Guide... (not sure whether that ultimately helps then, though...)
Any suggestions on how to make progress on this issue are welcome.
If a relay trace doesn't help, then the next thing would be to disas surrounding code at 0x004191fb and walk back the code flow to find out where the NULL %ecx was coming from.
PS: Congrats to the Wine team. I was most impressed how well HoI ran on wine.
Thanks!
Andreas Mohr
Hi,
On Thu, Aug 19, 2004 at 09:31:24AM +0200, Andreas Mohr wrote:
You should at least have used pipes as described in the User Guide... (not sure whether that ultimately helps then, though...)
Doh, make that Developers Guide, I think.
Andreas Mohr
On Thu, 2004-08-19 at 19:31, Andreas Mohr wrote:
Hi,
On Thu, Aug 19, 2004 at 06:43:14PM +1200, Simon Kitching wrote:
Backtrace: =>1 0x004191fb (0x406bfe94) 2 0x005af5b2 (0x406bff20)
All in app space, most likely. Not very useful, I'm afraid.
Yes, I had leapt to the assumption that the exception was occurring within Wine code. I shouldn't have assumed that.
And then is there a way to step through at the source rather than assembly level?
--> only if you have the game source ;-)
If the address 0x004191fb is within wine, then presumably there will be some way to determine the source line within wine?
And if it's in the game code, do people use c decompilers? Or is knowing x86 assembly code a requirement for debugging code that uses wine?
Any suggestions on how to make progress on this issue are welcome.
If a relay trace doesn't help, then the next thing would be to disas surrounding code at 0x004191fb and walk back the code flow to find out where the NULL %ecx was coming from.
I have some good news anyway. I still can't load the games I saved earlier. But I tried starting a new game, and can load/save happily. So the possibilities are: (a) that the problem was caused by a corrupt save-file being *created* when running with the debian wine release (Version: 0.0.20040615-1), and that now I am running with wine CVS HEAD, games are being saved properly. (b) that there is a bug in HoI, and that the saved game wouldn't have loaded on Windows anyway. I will test this theory soon by taking the save-game to a friend with a Windows copy and see what happens. It would be truly bad luck to strike an HoI bug the first time I try to run it under Wine, but stranger things have happened. (c) that the bug is wine-related, but only pops up sometimes. I can test this by playing a lot more games, and seeing if it happens again.
So for now, I'm going to suspend the wine debugging, and do some more playing instead :-)
Thanks for your help.
Cheers,
Simon
On Fri, 2004-08-20 at 12:00, Simon Kitching wrote:
Any suggestions on how to make progress on this issue are welcome.
If a relay trace doesn't help, then the next thing would be to disas surrounding code at 0x004191fb and walk back the code flow to find out where the NULL %ecx was coming from.
I have some good news anyway. I still can't load the games I saved earlier. But I tried starting a new game, and can load/save happily. So the possibilities are: (a) that the problem was caused by a corrupt save-file being *created* when running with the debian wine release (Version: 0.0.20040615-1), and that now I am running with wine CVS HEAD, games are being saved properly. (b) that there is a bug in HoI, and that the saved game wouldn't have loaded on Windows anyway. I will test this theory soon by taking the save-game to a friend with a Windows copy and see what happens. It would be truly bad luck to strike an HoI bug the first time I try to run it under Wine, but stranger things have happened. (c) that the bug is wine-related, but only pops up sometimes. I can test this by playing a lot more games, and seeing if it happens again.
So for now, I'm going to suspend the wine debugging, and do some more playing instead :-)
Just to end this thread, I have done some more "testing" :-) and the issue with being unable to load saved games has not reappeared. I still don't know which of the above theories was correct, but don't care now - it all "just works" (tm).
Thanks for the cool software.
Simon
I ran "winedbg HoI.exe" and got exactly the same behaviour, though with a bit more info:
<output> First chance exception: page fault on read access to 0x00000006 in
Normally means something like this:
struct something *a = 0;
a->some_member;
(obvious I guess but I thought i'd say anyway).
FWIW %ecx normally == this in C++ apps. So I'd say this was a vtable deref on a null object pointer.
32-bit code (0x004191fb). Register dump: CS:0073 SS:007b DS:007b ES:007b FS:003b GS:0033 EIP:004191fb ESP:406bf4ec EBP:406bfe94 EFLAGS:00210206( - 00 - RIP1) EAX:48258e60 EBX:00000000 ECX:00000000 EDX:007e5f44 ESI:418736c0 EDI:45ae16e3 Stack dump: 0x00000000: 00000000 00000000 00000000 00000000 0x00000010: 00000000 00000000 00000000 00000000 0x00000020: 00000000 00000000 00000000 00000000 0x00000030: 00000000 00000000 00000000 00000000 0x00000040: 00000000 00000000 00000000 00000000 0x00000050: 00000000 00000000 00000000 00000000 0x00000060:
Yes well stack dumping is kinda broke by the recent debugger changes.
Backtrace: =>1 0x004191fb (0x406bfe94) 2 0x005af5b2 (0x406bff20)
I don't think this is Wine code.
3 0x404ff9f2 start_process+0xf2(arg=0x0) [process.c:995] in kernel32 (0x406bfff4) 4 0x4002c151 wine_switch_to_stack+0x11 in libwine.so.1 (0x00000000) 0x004191fb: movl 0x6(%ecx),%ecx Wine-dbg>
</output>
I also tried the "WINEDEBUG=+relay" option as recommended in the wine docs. However after leaving the program running overnight, and having generated 3 gigabytes of log output, the point where the bug occurs hadn't been reached. I think that what's happening is that there is a thread (0011) which is driven by timer ticks [probably doing GUI or sound stuff], and that because HoI is running much more slowly under +relay, that the thread doing the load-game work (0009) isn't actually getting any CPU time at all. NB: the log was only 3GB because I used grep to discard output about RtlEnterCriticalSection and RtlLeaveCriticalSection. Without that, the log would be closer to 30GB!
You can use RelayInclude/RelayExclude in the config file to eliminate those.
Any suggestions on how to make progress on this issue are welcome. Pointers to documentation on debugging this sort of thing are very welcome.
It's tricky. For this sort of thing I'd normally work backwards from the disassembly but I'm not sure whether winedbg disassembly still works nicely with showing you API calls and such ....
One thing would be to try and disable any sound threads by switching sound off in the game so you can get a +relay,+tid trace.
thanks -mike