Drinking The Koolixir – Part 2

by

To get a better handle on Erlang’s behavior, I decided to install a popular set of tools for debugging and performance profiling: EPER. I think it stands for “Erlang PERformance tools”, but it could also mean “Everything Proves Erlang Rules” or “Egrets Prefer to Eat Robots” or really anything for that matter. One thing is for certain, however: getting these tools built and running on Mac OS X was fraught with danger and build errors.

Running the Test Suite

Before I got down to the business of trying to make and make install EPER, it made sense to run make test to ensure everything was in working order. Why start there? You know because tests. Seemed like a decent way to figure out how the system ticks, and learn a little more about how the pieces of the Erlang environment fit together.

Problems Arise

EPMD

Right off the bat, I ran into issues with eunit tests not passing. Specifically, the first run of make test yielded the following:

=INFO REPORT==== 4-Mar-2015::19:05:02 ===
Protocol: "inet_tcp": register/listen error: econnrefused
prfDog: t0_test (module 'prfDog')...*failed*
in function prfHost:assert_proxy/1 (src/prfHost.erl, line 67)
in call from prfHost:start/4 (src/prfHost.erl, line 26)
in call from prfDog:t0_test/0 (src/prfDog.erl, line 178)
**exit:{no_proxy,nonode@nohost}

The solution? Start epmd in “daemon” mode:

epmd -daemon

That solved the issue, but does raise some more questions. Like: What the heck is epmd? How do I manage this service on a Mac? Is it lunchy compatible? launchd? initctl? I will definitely be digging deeper into epmd in a future post. For now, we march onward through Error Canyon.

GTKNode

The installation process next failed because gperfGtk claims it is missing some dependencies:

src/gperfGtk.erl:386: Warning: gperfGtk:g/1 calls undefined function gtknode:cmd/2 (Xref)
src/gperfGtk.erl:37: Warning: gperfGtk:init/0 calls undefined function gtknode:start/1 (Xref)
src/sherk.erl:567: Warning: sherk:g/1 calls undefined function gtknode:cmd/2 (Xref)
src/sherk.erl:56: Warning: sherk:init/0 calls undefined function gtknode:start/1 (Xref)
ERROR: xref failed while processing /Users/BTidwellGrio/Code/elx_workspace/eper: rebar_abort
make: *** [xref] Error 1

A little Googling turned up the fact that gtknode is an OSS Erlang library for mapping to the popular UI library, GTK. I pulled down the repo, and after a little more digging, found the command for building and installing it:

aclocal ; autoconf ; automake ; ./configure --prefix=/your/cool/prefix ; make ; make install

For the prefix here, I personally like to keep all of my shell/library Erlang in a .erllib folder in my home directory. I track a couple of helper files in the same folder in a dotfiles repo, and ignore the build output of all the remaining libraries.

The first run of the gtknode build exited with:

Checking for GTK... no
configure: error: Package requirements (gmodule-2.0 libglade-2.0 gtk+-2.0,
gdk-pixbuf-2.0) were not met:

Package 'libxml-2.0', required by 'libglade-2.0', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

This story checks out; it seems pretty obvious that something named gtknode would be dependent upon GTK. The README for gtknode encourages the use of Homebrew to install glade (amongst a myriad other things). This first required adding the X11 homebrew tap. Additionally, a couple more runs of the build script revealed a dependency on XQuartz, which is easily managed using Homebrew Cask. As I had never used Cask up to this point, I have included it in the installation steps below:

brew tap homebrew/x11
brew install glade fontconfig freetype libpng
brew install caskroom/cask/brew-cask
brew cask doctor # This triggers a sudo prompt to configure needed directories
brew cask install xquartz

Since we installed glade and some of the other libraries using Homebrew, running another build will result in"Package 'xcb-shm', required by 'cairo', not found" (or any number of other "[Package] not found" errors). I am not completely familiar with pkg-config, but it seems the gist of the problem is that Homebrew installs binaries and libraries in non-default locations (at least from a Linux perspective). This can be fixed by exporting the pkgconfig environment variable*:

PKG_CONFIG_PATH=/usr/local/opt/libxml2/lib/pkgconfig:/usr/local/lib/pkgconfig:/opt/X11/lib/pkgconfig

*This lovely bit of minutiae comes courtesy of a completely unrelated page in the node-canvas Wiki.

With all this in place, gtknode should compile, and make test from the eper project root should pass. Then, the EPER project can be built using the same tune as gtknode:

aclocal ; autoconf ; automake ; ./configure --prefix=/your/cool/prefix ; make ; make install

Using EPER in Your Environment

Now that these libraries are compiled and installed using the prefix we provided earlier, we can add them to the Erlang shell using the ERL_LIBS environment variable. If you used the same convention stated here (i.e. .erllib in the home directory), then this variable should look like the following:

export ERL_LIBS="$HOME/.erllib/lib/erlang/lib"

On startup, the Erlang shell will load any source code in the ebin directory of any libraries contained under the ERL_LIBS directory. If you refresh this environment variable and then run erl from the command-line, you should be able to sanity-check installation of EPER by running redbug:help(). inside the Erlang shell. This should output a list of methods supported by Redbug.

These tools are helpful not only for general debugging tasks, but also for learning Erlang in a much more disciplined way. Now, when something goes wrong deep in the depths of some function, it is simple enough to dig deeper using redbug instead of relying on guesswork. This may deserve a dedicated post on redbug or just be interwoven with future blog posts, but either way you can expect to see more about proper redbug usage in this series.

Leave a Reply

Your email address will not be published. Required fields are marked