The Xcode visual debugger is really nice and easy to use. It turns out it’s possible to get it to play well with MPI code (although it may not work for actually multithreaded processes). This seems to be pretty buggy, but it does work. I’m not sure how useful this guide is to others, but honestly I’m writing it to remember how to do this in the future.
mpic++ is just a wrapper for the system C++ compiler, but on my system is defaults to g++ and we want to switch to c++ (the Apple C compiler). To start, we use the
--show-me:compile flag with our usual compilation command
mpic++ --show-me:compile *.cpp
This doesn’t actually compile the code, it just tells you the command that would have actually been executed with the C compiler. In my case the output is:
g++ config.cpp main.cpp mtrand.cpp -I/usr/local/include -L/usr/local/lib -lmpi
We’re going to take all those flags and put them after the Apple C compiler like so:
c++ -g config.cpp main.cpp mtrand.cpp -I/usr/local/include -L/usr/local/lib -lmpi
Don’t forget to add the debugging flag
-g. This command produces a binary file
a.out. Before we can run it, we need to get Xcode ready.
Launching the Debugger
Open the Xcode project. On the menubar, select Debug–>Attach to Process by PID or Name…
In the resulting window, enter the name of the executable (this this case
a.out) and click “Attach”.
Now we’re ready to actually run our simulation using the normal command in the terminal:
mpirun -np 1 ./a.out
When you switch back to Xcode, you should be able to use the debugging interface like normal. If it doesn’t come up automatically you may have to click on the debugging logo in the navigation bar on the left side of the window (circled below).
Trouble attaching to process?
For some reason I find that Xcode cannot attach to the process using this procedure often with an error like “Message from debugger: error 1”. I haven’t been able to figure out exactly why this happens or how to avoid it altogether. My use case is way outside what Xcode is designed for (i.e. building iOS apps). Overall I found that using the stop button within Xcode to kill the process (rather than killing it from the terminal) seems to make this problem less likely, but it still happens.
Once this problem occurs, the only solution I have found is to recompile the binary, naming it something else using the
-o othername.out flag (renaming an existing binary won’t work), attaching the debugger to the new binary and then running the new binary.