Code: Select all
[bhs.dll] Failed to load, error 998. No access to memory location.
I tried manually patching this check out of the binary, but that just leads to other DLLs complaining about things being missing. It's definitely required.
Unfortunately the community lost the source to this DLL years ago and the game works without this problem on Windows (so there's nothing to try and debug there). Most of the community has moved onto a much newer codebase for their mods, which works perfectly fine under Wine (as does the base game), but this one particular mod is stuck on an old codebase due to some non-derivative license/cultural restrictions put in place by previous authors.
I've been trying to get this mod running under Wine for well over a year (on and off) across wine versions from the 3.x era up to 4.6. Throughout I've had the same debugger issues, none of this is due to a recent change as far as I can tell.
For reference however:
- Current Wine version: 4.6
- Current Platform: x86_64 Void Linux 4.19.30_1
- 32bit wine prefix
WINEDEBUG=+relay and +all
I have not been able to notice anything useful in here using my feeble logreading skills. The game seems to catch whatever fault is occurring and gracefully bring a MessageBox up.
Download link for log files (9.3M compressed)
Landmark 1: line 1009245 in allog.txt:
Code: Select all
14561.530:0008:0009:Ret KERNEL32.LoadLibraryA() retval=00000000 ret=110025c2
14561.530:0008:0009:Call KERNEL32.GetLastError() ret=110025c9
14561.530:0008:0009:Ret KERNEL32.GetLastError() retval=000003e6 ret=110025c9
14561.530:0008:0009:Call KERNEL32.CreateFileA(1128a154 "dllload.txt",40000000,00000003,0034d6c0,00000004,00000080,00000000) ret=1123f889
Landmark 2: "there was an error loading bhs.dll" message box. This happens far after the fault itself.
winedbg
Code: Select all
winedbg --gdb Game300.exe
I'm not aware of a winedbg feature to get it to trip on this fault.. I might be missing something here.
winedbg --gdb
This immediately fails:
Code: Select all
winedbg --gdb Game300.exe
0039:003a: create process 'C:\w3dhub\games\ecw-testing\Game300.exe'/0x1107c8 @0x78f4ef (0<0>)
winedbg: Internal crash at 0x7e97ae8f
Call me green, but I have no clue where to start when it comes to debugging a debugger
gdb with workarounds
This is the best I've been able to come up with so far:
1. Run "wine Game300.exe" in a terminal, and then immediately hit Ctrl+Z to suspend it
2. gdb -p $(pgrep Game300.exe)
3. "fg" in the game's terminal
The game will still stay suspended because of gdb being attached to it; but I have found it is important to run the 'fg' to get it out of STOP mode otherwise it's unreliable to start up again from inside gdb.
4. gdb: catch syscall clone
5. gdb: cont
The first call of 'cont' will provide a notice about the process having received a SIGCONT (from typing 'fg' in the terminal).
If I keep cont'ing then after the 12th thread starts and closes I hit a segfault. GDB actually detects this segfault and halts program execution.
I think this segfault is normally being masked/hidden/something during normal execution (so the game can provide its error log + dialog box). I'm not an expert on DLL loading (I'm a Linux person) so I'm not sure what the conventions are here.
Throughout this process GDB is clueless as to what files each frame is in. Example:
Code: Select all
(gdb) info threads
Id Target Id Frame
* 1 LWP 4739 "Game300.exe" 0xf7c4f9b4 in ?? ()
2 LWP 4836 "Game300.exe" 0xf7f29df9 in __kernel_vsyscall ()
5 LWP 4852 "Game300.exe" 0xf7f29df9 in __kernel_vsyscall ()
7 LWP 4858 "Game300.exe" 0xf7f29df9 in __kernel_vsyscall ()
8 LWP 4863 "Game300.exe" 0xf7f29df9 in __kernel_vsyscall ()
9 LWP 4866 "Game300.exe" 0xf7f29df9 in __kernel_vsyscall ()
10 LWP 4885 "Game300.exe" 0xf7f29df9 in __kernel_vsyscall ()
11 LWP 4890 "Game300.exe" 0xf7f29df9 in __kernel_vsyscall ()
12 LWP 4901 "Game300.exe" 0xf7f29df9 in __kernel_vsyscall () # newest one
(gdb) thread 12
(gdb) bt
#0 0xf7f29df9 in __kernel_vsyscall ()
#1 0xf7d2e147 in ?? ()
#2 0x7bc9360d in ?? ()
#3 0x7bc4e49e in ?? ()
#4 0x7bc98ffa in ?? ()
#5 0x7bc94aa4 in ?? ()
At the time of the segfault the program has jumped somewhere weird that I presume isn't supposed to be code:
Code: Select all
> 0xec83f0e4 add %al,(%eax)
0xec83f0e6 add %al,(%eax)
0xec83f0e8 add %al,(%eax)
0xec83f0ea add %al,(%eax)
0xec83f0ec add %al,(%eax)
0xec83f0ee add %al,(%eax)
0xec83f0f0 add %al,(%eax)
0xec83f0f2 add %al,(%eax)
0xec83f0f4 add %al,(%eax)
0xec83f0f6 add %al,(%eax)
...etc for a very long time...
I'm not sure of a way to reliably break before the error occurs. If I try to single-step the game (stepi): then I get no-where. The game runs in a loop that prioritises filling the audio buffer above everything else, so even if I run "stepi 10000" over and over again I still don't progress toward the crash.
VS2005 and VC2008
(Visual studio 2005 was used to compile the culprit DLL)
After lots of wrangling I managed to get 2005 (and 2008 on another attempt) to install; however they completely fail to be able to debug processes. Even simpler ones that normally work with windbg.
Other 3rd party debuggers
ollydbg110: crashes when I try to open the exe
ollydbg200: loads and analyses the exe, but hangs when trying to start the debugging process
x64dbg (32-bit version): fails to open any & analyse any exe file, seems broken under Wine despite the winehq page saying otherwise.
dependency walker: thinks all of the system dlls have missing exports (probably due to them being dummies under wine) and seems blinded because of it.
Questions
(1) Is there an easier way to debug DLL loading in Wine? Ie debug the init funcs of a DLL, or WINEDEBUG for newly spawned threads only?
(2) Is there a way to get winedbg --gdb working? When this works I at least get more useful backtraces, because gdb knows what the files are.
(3) Am I doing something horribly wrong? Can anyone suggest some easier or better alternative paths?