Debugging: Difference between revisions

From Arx Libertatis Wiki
Jump to navigation Jump to search
Line 83: Line 83:
* Automatic backtraces generated by wine when no debugger is attached only work when arx was started using <code>wine64 arx.exe.so</code> instead of <code>wine arx.exe.so</code> or <code>./arx.exe</code>
* Automatic backtraces generated by wine when no debugger is attached only work when arx was started using <code>wine64 arx.exe.so</code> instead of <code>wine arx.exe.so</code> or <code>./arx.exe</code>


== Windows ==
== Windows (MSVC debugger) ===
=== Gdb ===
=== MSVC debugger ===


See [[Downloading and Compiling under Windows]]
See [[Downloading and Compiling under Windows]]

Revision as of 20:00, 17 September 2011

This article explains how to debug Arx Fatalis on the different targeted platforms.

Linux

TODO: This information is outdated as we have a native linux build now.

Currently arx is not compiled as a native linux application, but as a winelib application that must be run with wine. This makes debugging a little more tricky.

Winedbg

To debug just run arx.exe.so with winedbg instead of with wine:

WINEDEBUG=-all winedbg ./arx.exe.so

Winedbg does not support C++ however. This means that backtraces won't show filename and line numbers for any non-C symbols (anything that is in a class or namespace). You also cannot set a breakpoint on C++ symbols.

Gdb

Using gdb allows to interact with C++ symbols. Since arx.exe.so is a winelib application, you can't run it directly with gdb , but winedbg supports automatically attaching gdb to the process when it starts:

WINEDEBUG=-all winedbg --gdb arx.exe.so

However, wine causes many segmentation faults internally (and handles them), which causes gdb to suspend the execution of the program. To tell gdb not to do this, enter the following into the gdb prompt:

handle SIGSEGV nostop noprint

This also prevents gdb from catching any segmentation faults caused by arx, which then exits and gdb just prints "Program exited normally." In those cases plain winedbg may still be needed.

Wine will also send a SIGTRAP once on startup, but SIGTRAP is also used by gdb, so ignoring it disables all breakpoints.

Many stl classes check for error conditions when compiling in debug mode and throw an exception on failure. To get a backtrace for where the exception was thrown, add a breakpoint on the exception constructor. Enter this in the gdb prompt.

b std::logic_error::logic_error

b std::runtime_error::runtime_error

If entering these commands into gdb on each run is to cumbersome, you can create a file called ".gdbinit" that is loaded by gdb on startup and contains default settings for gdb:

set breakpoint pending on
b std::logic_error::logic_error
b std::runtime_error::runtime_error
handle SIGSEGV nostop noprint

The extra "set breakpoint pending on" is needed because .gdbinit is loaded before any libraries and therefore gdb will not be able to find the breakpoints right away.

With this configuration, gdb will still stop twice during startup, once for a SIGSEGV and once for a SIGTRAP, both in wine. Use cont or just c each time to continue.

Attaching to existing processes

If arx has been started normally with wine you can also attach gdb to the running process, however each gdb session can only attach to one thread.

Start gdb using gdb wine and then find the tids of the arx threads using ps -A -L | grep arx.exe.so. The ids needed are those from the second column and the first result (same id for both columns) should be the main thread. Attach to it in the gdb promt using attach <tid>.

Valgrind

Like gdb, valgrind also needs a little help to run with wine. Specifically the --trace-children=yes and --vex-iropt-precise-memory-exns=yes options are needed. Here is the full command to debug arx with the memcheck tool:

valgrind --tool=memcheck --error-limit=no --leak-check=full --log-file=arx-valgrind.log -v --trace-children=yes --vex-iropt-precise-memory-exns=yes --track-origins=yes --suppressions=suppressions.txt -- wine arx.exe.so

Where suppressions.txt is the one found here: http://www.stud.uni-karlsruhe.de/~uocet/suppressions.txt

I get a warning preloader: Warning: failed to reserve range 00110000-68000000 from wine when running arx with valgrind, but the game seems to run anyway. Be patient, it will take a while before there is any console output from arx and even longer before the first frame renders.

The --track-origins=yes option slows down execution some more (arx is already unplayable without it), but provides useful additional information.

To speed things up a bit, you can prevent the wineserver from being debugged by valgrind. This can be done by running another wine app before starting arx with valgrind (and not closing it before arex starts). For example:

winemine &

For mor information on wine and valgrind see http://wiki.winehq.org/Wine_and_Valgrind

Debugging 64-bit builds

64-bit wine need some extra care for gdb to work.

  • Winedbg works, but you have to start it using wine64 winedbg instead of just winedbg
  • winedbg --gdb doesn't work.
  • Attaching to existing processes with gdb works, but you need to start arx using wine64 arx.exe.so instead of wine arx.exe.so or ./arx.exe *and* you need to start gdb using gdb wine64 instead of gdb wine.
  • Valgrind doesn't work.
  • Automatic backtraces generated by wine when no debugger is attached only work when arx was started using wine64 arx.exe.so instead of wine arx.exe.so or ./arx.exe

Windows (MSVC debugger) =

See Downloading and Compiling under Windows