Sunday, December 07, 2008

Mac OS X Debugging Adventures

For the past few months, I've been spending some of my free time working on a cross-platform screensaver, one that runs under Windows and under Mac OS X. Getting the Windows version up and running was relatively easy. A Windows screensaver is just an exe with a special extension (.scr) and some code to handle a few special command line parameters. Having written Windows game code before helped there. Getting the Mac OS X version running was quite a bit trickier, due in part to my inexperience with OS X. I place some blame on OS X's screensaver engine though, which ended up being rather tricky to work with. It deals with screen savers in a very different manner than Windows' approach. OS X expects screensavers to be represented not as standalone applications, but as dynamically loadable modules, which can be loaded via one of a few different OS X-provided applications.

Every OS X screensaver module must adhere to a certain set of guidelines. Among them, they must be represented as an OS X bundle, they must provide a subclass of the OS-provided ScreenSaverView class, and they should play nice with other screensaver modules. Sounds ok, except I found the implementation of these guidelines to be a bit tricky. Why?


  1. OS X screensavers are subject to control via an external main loop, which each screensaver hooks into (for initialization, shutdown, time-stepping, drawing, etc.) This design seems ok in some ways: having no main loop to create reduces the amount of code needed for each screensaver to implement. I could see ways in which this could be easier for the beginner. In my case, there have been times that I've wanted to debug and profile portions of my screensaver logic using a main loop of my own, and without having to deal with the OS X screensaver engine.
  2. All OS X screensaver modules get loaded into the same address space. Furthermore, they get loaded in such a way that no two modules can share the same symbol names. If two modules implement a function with the same name, there's a good chance one or both of them will crash, even if only one of the two modules is actively displaying a screensaver. One solution to this is to name functions such that they don't clash, such as by appending a unique name to each function. Another solution, the one I chose to work with, is to load almost everything in a second dynamically loaded module, which gets loaded in such a way as not to cause naming clashes (via dlopen with RTLD_LOCAL.)


For the times when I want to debug or profile my app without OS X's screensaver engine getting involved, I can switch to Windows and use that version. I don't always want to switch to Windows though, so I created a small Mac app to help with debugging. It loads the platform-independent portions of the screensaver code and drives them via its own main loop, avoiding the OS X screensaver engine altogether. I recently ran into a problem with that approach though. I created the app, ran it, confirmed that it worked, then hit a case where I wanted to step into the screensaver code. When I tried to launch the app with a debugger attached, the app would immediately crash. It's main function would never get called, and I'd be stuck with a debugger command prompt and the following error message:


dyld: Library not loaded: @loader_path/../Frameworks/libBox2D.dylib
Referenced from: /Users/davidl/Documents/Code/Platformer/trunk/MacOS/build/Debug/Lugnut_Native.so
Reason: image not found
Program received signal: “SIGTRAP”.
Xcode: Introspection dylib not loaded because thread 1 has function: __dyld_dyld_fatal_error on stack


To note, Lugnut_Native.so is the current name of the shared library that contains most of my screensaver code, and libBox2D.dylib is another shared library that it depends on. "Platformer" is the original name of the project, which started out life as a 2d platformer, and eventually evolved into a screensaver having nothing to do with 2d platformers. Such is life.

The error message listed above says that my screensaver library, Lugnut_Native.so, can't load one of its dependencies, libBox2D.dylib. It's looking for it, and it can't find it.

A bit of background info: "@loader_path" is a term that has special meaning to the Mac OS X dynamic linker. When one module tries to load another module, it can use the token, "@loader_path" to indicate that the module to be loaded is located relative to the location of the module doing the loading. In this case, the module Lugnut_Native.so was trying to load another module, libBox2D.dylib, and it was trying to load it from a location relative to itself. Both modules were supposed to be located on my hard disk in locations predictably relative to each other. This is where "@loader_path" came in. It says that Lugnut_Native.so should expect that it's dependent library, libBox2D.dylib, in located spot relative to itself. The OS X dynamic linker replaces "@loader_path", with the path of the directory that Lugnut_Native.so exists in.

The problem ended up being that the wrong copy of Lugnut_Native.so was being loaded. There were two copies of the file, both getting created in the app's XCode-driven build process. The first was created by the linker. This was the copy that was getting inadvertently loaded. The second copy, the one I wanted to load, was a copy of the first placed inside the app's bundle, a location where OS X was supposed to be able to find it. In some cases, OS X would find it. If I ran the app outside of XCode, everything was ok. When I ran it from within XCode with a debugger attached, it'd crash immediately. Why would it do this?

The latter copy was the one I wanted to load. It existed inside the app's bundle. The copy that was getting loaded wasn't. When the OS X dynamic linker tried to load the incorrect copy, it was unable to find libBox2D.dylib in the specified location!

The solution I used, and there may have been several, was to tell XCode that when it launched the app, the dynamic loader should try to load dynamic libraries from a specific location, namely the directory where the desired copy of Lugnut_Native.so existed (inside the main application's bundle, to note.) It did this by making sure an environment variable called DYLD_LIBRARY_PATH was set, and that it got set before the app launched. DYLD_LIBRARY_PATH, when set, tells the OS X dynamic linker to load dynamic libraries from a given path. By setting this variable to the location where the desired copy of Lugnut_Native.so was, the dynamic linker should load it, or so I hoped at the time.

When the app crashed, it presented me with a command prompt, with which I was able to list the environment variables exposed to the app and to the dynamic linker. The command, "show environment" (without the quotes), said that DYLD_LIBRARY_PATH was already set and that it pointed to the path with the incorrect copy of Lugnut_Native.so. If there were a way to tell XCode to set DYLD_LIBRARY_PATH to something else, maybe I would be able to debug my app.

As it turns out, there was a way to set DYLD_LIBRARY_PATH before the app ran, thus making sure that the correct copy of Lugnut_Native.so would load, and thus allowing me to debug my screensaver in the manner I was hoping for. Here are the steps I took, minus most of the annoying missteps I ran into:


  1. Under the "Executables" section of the XCode project, I clicked on the app to debug, then pressed Command-I to bring up its Info dialog.
  2. Clicked on the "Arguments" tab of the dialog that came up.
  3. In the section, "Variables to be set in the environment:" section, I clicked on the plus sign to add an entry.
  4. In the new entry, I set the name to be DYLD_LIBRARY_PATH, and the value to "$SRCROOT/$CONFIGURATION_BUILD_DIR/$FRAMEWORKS_FOLDER_PATH", without the quotes. The value here told the dynamic linker to try loading modules from the application's bundle first and foremost, which is where the correct copy of Lugnut_Native.so was to exist. Furthermore, it gives the dynamic loader a full path name, rather than a relative one. This turned out to be important. When I tried setting DYLD_LIBRARY_PATH to just, "$CONFIGURATION_BUILD_DIR/$FRAMEWORKS_FOLDER_PATH", it didn't work, which is not what I was expecting. $CONFIGURATION_BUILD_DIR, when used elsewhere in XCode, usually resolves to a full path name. Prefixing "$SRCROOT" to this value fixed it.
  5. I closed the dialog and then launchd the app in the debugger (via XCode's "Run" menu.) It worked!


From then on in, I've been able to debug my screensaver under OS X using a main loop of my own creation, which is a bit more flexible than trying to debug the screensaver via OS X's screensaver engine. Listing the reasons why are beyond the scope of this blog posting, perhaps some other time I'll list them. Time for a break. :-)

Friday, June 20, 2008

Harvard Square WiFi

Free WiFi was recently installed in Harvard Square. Earlier today, I tried getting access to it and had a moderate amount of luck. The places I was able to get it working included:

  • in the little park just outside the Peet's Coffee on Mt. Auburn and JFK. The signal was ok there.
  • in the tea cafe adjacent to the Fire & Ice. The signal was rather spotty here; I was able to get a usable connection on one side of the cafe and not the other.

The free wifi did not work inside the Starbucks, which does provide WiFi, although it's rather expensive. It's supposed to get cheaper at some point soon. According to one Starbucks employee I talked to, 'maybe by September'. My fingers are crossed. I enjoy changing up where I work and am fortunate enough to be able to do so. Mixing the pervasiveness of Starbucks with reasonably-priced WiFi spots sounds good to me.

Monday, March 24, 2008

Building Visual C++ Apps on the Command Line

I recently started spending some time working on my laptop; in coffee shops, libraries, etc. Much of my work involves working in C++, which means that I've gotta spend time compiling. Unfortunately, my laptop is old. Running Visual C++ on this machine, which I need for much of my work, is like putting it on a treadmill turned up to high. It's ok for a while, but gets tiring awfully fast. Visual C++ on my desktop machine isn't a problem. It's got gobs of memory and a nice dual core CPU. A few days away from it has made me realize just how spoiled I've become by it.

Fortunately, Visual C++ can do builds on the command line. Editing can be done in a less memory intensive application, which in my case, means that my laptop won't have to use the hard disk when it runs out of memory, something that happens all too quick these days.

Here's how to do it, or rather, here's at least one way to do it:

First, a command prompt needs to be set up for use with the Visual C++ toolset. There are two ways to get this running:


  1. Launch a command prompt and run the batch file, vcvarsall.bat. On my laptop, this is installed to C:\Program Files\Microsoft Visual Studio 8\VC\. I installed Visual C++ 2005 to the default location. If you've got this installed, it's probably in there too.
  2. Open the "Visual Studio 2005 Command Prompt" shortcut that the Visual C++ 2005 installer creates. It's in the, "Visual Studio Tools" folder.


Once you've got a command prompt window open, CD into the directory where your .sln file exists. From there, to build all configurations (Debug, Release etc.), type in the following command:

vcbuild TheApp.sln

If you'd like to build just one project configuration, perhaps "Debug", then type in the following:

vcbuild TheApp.sln Debug

That's it! Nice and simple, no IDE required. Of course, you'll lose out on things like a debugger, or the ability to point and click your way to build management, however there are ways to do those outside of the IDE. In my case, I figure I can wait to do those when I'm at my nice and fast desktop machine, or I can just run the full Visual Studio IDE on my laptop every once in a while.

Update: More information can be found on VCBUILD here:


Update #2: Turns out VCBUILD has a problem regarding dependencies. If one use Visual Studio's Configuration Manager to set up a linker dependency for a C++ project, VCBUILD won't use that information. It'll build the projects, but will not build the projects in the correct order, nor will it pass the correct information to the linker . One workaround is to use DEVENV.EXE, which serves both as the exe for the full IDE, and as a way to build projects at a command prompt. It's a bit different than VCBUILD, and I didn't notice any way to build all configurations in a .sln, but it can be utilized to build individual ones. For example, to build the configuration, "Debug", the following can be used:

devenv.exe TheApp.sln /Build Debug

To note, this will not launch the full IDE; it will build the app, use the current console window for logging, and then exit, just like VCBUILD. No GUI will be shown.