Skip to content

Debugging OpenRCT2 on macOS

Margen67 edited this page Apr 22, 2021 · 2 revisions

The information on this page is very outdated and concerns the mingw target only. Just use lldb for native builds.

When debugging with winedbg, you probably found out that you can't:

  1. Set break/watch points (not even using the literal address),
  2. Use debug symbols.

To debug OpenRCT2 with these features, a particularly strange setup has to be used. I've been searching for ways to debug cross-compiled MinGW executables, and finally found this StackOverflow post: https://stackoverflow.com/questions/3720434/can-gdb-be-used-on-a-cross-compiled-win32-application-on-the-target-platform

In summary, the setup is as follows:

  1. Use a gdbserver executable compiled with i686-w64-mingw32 as host (So when you've compiled gdbserver, the result is gdbserver.exe)
  2. Use a gdb executable compiled with i686-w64-mingw32 as target (So the "host" is native)
  3. Start gdbserver.exe using wine, e.g.: wine gdbserver.exe :0 openrct2.exe A port number will now be shown, this is the port you should connect to in step 4.
  4. Start gdb and connect to the server with target remote :[gdbserver-port-number]
  5. run set sysroot /path/to/sysroot (most of the time this is ~/.wine/drive_c) in GDB
  6. run set solib-search-path in GDB

After this, you can set breakpoints as you like!

Compiling gdbserver and gdb

  1. Compiling gdb

    First, we compile gdb. To do this, we need a gcc compiler and the gdb source code. On later versions on OSX, gcc has been replaced with clang. So use a gcc compiler installed with MacPorts or HomeBrew. I used MacPorts' gcc49 package.

    1. Grab the gdb source from GNU: https://www.gnu.org/software/gdb/download/. I used version 7.8.
    2. Configure gdb using the following command in the root directory. That is, in the directory gcc-[version], and not gcc-[version]/gcc:
    $ CXX=g++-mp-4.9 CC=/opt/local/bin/gcc-mp-4.9 CFLAGS="-I/opt/local/include -L/opt/local/lib" ./configure --target=i686-w64-mingw32 --disable-werror
    

    I set the CFLAGS variable so that it also includes /opt/local/include and /opt/local/lib in its library/header search paths. These are for MacPorts, but you have to set it to the correct directory yourself if you use a different system.

    Replace gcc-mp-4.9 and g++-mp-4.9 with your own C and C++ compilers.

    1. Then, build it using make.

      Running this, you may run into an error looking like this:

      Undefined symbols _bfd_mach_o_lookup_command in machoread.o
      

      This is because bfd (located in the subdirectory called bfd) hasn't been compiled with Mach-O, because we specified a custom target.

      To workaround this problem, go to the bfd subdirectory, and run the same configure command above, except with --enable-targets=all. Then, still in the bfd subdirectory, run make.

      When that's done, go to the top-level directory again (cd ..) and run make again. Now it should compile.

    2. When it's done, you can find gdb in the gdb subdirectory. Place the executable wherever you want. I placed it alongside the other MinGW toolchain binaries. (located in /usr/local/mingw-w32-bin_i686-darwin/bin if you ran the install.sh script for OpenRCT2):

      $ sudo cp gdb /usr/local/mingw-w32-bin_i686-darwin/bin/i686-w64-mingw32-gdb
      
    3. (optional) For more ease of use, I also used --with-sysroot=/path/to/your/.wine/drive_c as option with the configure script. To do this, go to the gdb subdirectory and run the same configure command as above, but now additionally with --with-sysroot=/path/to/your/.wine/drive_c. Now, still in the gdb subdirectory, run make again.

      Having done this, you don't have to set the sysroot path everytime you start gdb. It will locate wine's DLLs automatically.

  2. Compiling gdbserver

    Next, we compile gdbserver. This should be relatively painless, unlike the previous step.

    $ cd gdb/gdbserver
    $ ./configure --host=i686-w64-mingw32
    $ make
    

    i686-w64-mingw32-gcc should be used automatically. If not, check if it's in your path.

    The result is gdbserver.exe. I copied this to /usr/local/cross-tools/i686-w64-mingw32/bin, to keep everything organized.

Running the server and connecting

  1. To run the server:
    $ wine /path/to/gdbserver.exe :0 openrct2.exe
    
  2. Then, run gdb:
    $ i686-w64-mingw32-gdb openrct2.exe
    
  3. Once in gdb, run:
    target remote :[gdbserver-port-number]
    
  4. Be sure to load OpenRCT2 debug symbols, which are compiled with openrct2.dll:
    set solib-search-path
    
Clone this wiki locally