4.2 KiB
4.2 KiB
How to Debug Waterbox and Cores
Bring lots of tools, and lots of self loathing.
Windows
gdb
- Usually comes from mingw, or something
- Example script to attach to a running BizHawk instance:
#!/bin/bash PSLINE=$(eval "ps -W | grep EmuHawk") if [[ $PSLINE =~ [0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+([0-9]+) ]]; then gdb --pid=${BASH_REMATCH[1]} fi
- Thinks we're in x86-32 mode because of the PE header on EmuHawk.exe. We're not.
You can put this in
~/.gdbinit
(or maybe add it to the startgdb script?)set arch i386:x86-64
- The waterbox files have DWARF information, which gdb can read. If you build a waterbox core in debug mode,
you even get full source level debugging. With the new rust based waterboxhost, these symbol files should automatically
be registered for you as waterboxhost hits a gdb hook.
- The gdb hook is experimental, so be ready with
add-sym foobar.wbx
if needed.
- The gdb hook is experimental, so be ready with
- Has no way to understand first chance vs second chance exceptions. Since lazystates was added, the cores now
emit lots of benign SIGSEGVs as the waterboxhost discovers what memory space they use. You can suppress these exceptions:
But if the real exception you're trying to break on is a SIGSEGV, this leaves you defenseless. You probably want to use thehan SIGSEGV nos nopr
no-dirty-detection
feature in waterboxhost to turn off these SIGSEGVs for some kinds of debugging. - Also understands symbols for waterboxhost.dll, since that was actually built with MINGW.
b rust_panic
to examine rust unwinds before they explode your computer.- Breakpoints on symbols in the wbx file just don't work a lot of the time.
- This is the single worst part of modern waterbox debugging. I have no idea what gdb is doing wrong. It sees the wbx
symbols and can print stack information and tell you what function you're in, and print globals, but
b some_emu_core_function
just doesn't get hit. I think it might have something to do with how we map memory. This worked in some previous waterbox editions, but I never got to the bottom. - Recompile cores with lots of
__asm__("int3")
in them? Heh.
- This is the single worst part of modern waterbox debugging. I have no idea what gdb is doing wrong. It sees the wbx
symbols and can print stack information and tell you what function you're in, and print globals, but
windbg
!address
,!vprot
are useful for examining VirtualQuery information.- Can't read any symbols, which makes it mostly useless until you've narrowed things down heavily.
- Has more useful stack traces than gdb, as gdb usually can't see the stack outside DWARF land.
- Understands first and second chance exceptions.
sxd av
will do exactly what we need for lazystate page mapping; break only when our handled decides not to handle it.
- Can give reasonable information on random WIN32 exceptions with
!analyze
OmniSharp
- Great visibility into C# exceptions, pretty worthless otherwise.
General unwinding hazards
- Within the guest, DWARF unwinding information is available and libunwind is used. Guest C++ programs can freely use exceptions,
and Mednafen does so without issue.
- Trying to unwind out of the guest stack will not work, so there needs to be a top level catch.
- SEH unwinds, either from C# or Rust code, while in a callback from guest code back to host code, will unwind fine, but they will skip right past the guest code. This recovers the host system, but means that the guest is likely hosed as it had no chance to run any dtors.
- Any unwinding on a libco cothread will likely make me laugh.
Linux
gdb
- Only game in town here.
- Mono seems to use a lot of custom signals for... something.
- This script will start gdb, ignore those signals, and start EmuHawk:
#!/bin/bash gdb -iex "han SIG35 nos" -iex "han SIG36 nos" --args mono ./EmuHawk.exe "$@"
- This script will start gdb, ignore those signals, and start EmuHawk:
- Because you're actually in linux, beware function names:
b mmap
can mean the host libc's mmap, the rust implementation of the guest mmap, or the guest libc's mmap. - Same general problem with intermittently functional guest breakpoints as Windows. Heh.
- Same lazystate SIGSEGV problem (and same solutions) as Windows.
- Can see some mono symbols, which is sometimes useful.
- If you're looking for a pure core bug, this might be a better environment to test it on than Windows. It depends.