Gradual Epiphany

18Dec/090

Running erl in a debugger

Posted by dizzyd

Let's say you need to debug a port driver in Erlang. This typically involves gdb (unless you prefer the printf route). Go to where erlang is installed and edit the bin/erl script. Change the last line from:

exec $BINDIR/erlexec ${1+"$@"}

to:

if [ ! -z "$USE_GDB" ]; then
gdb $BINDIR/erlexec --args $BINDIR/erlexec ${1+"$@"}
else
exec $BINDIR/erlexec ${1+"$@"}
fi

Now all you have to do to get Erlang running in gdb is:

$ export USE_GDB=1
$ erl

If all goes well, you should see something like:

(dizzyd@sigr).(~)% export USE_GDB=1
(dizzyd@sigr).(~)% erl
GNU gdb 6.3.50-20050815 (Apple version gdb-1344) (Fri Jul 3 01:19:56 UTC 2009)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .. done

(gdb) r
Starting program: /Users/dizzyd/Applications/erlang-r13b03/lib/erlang/erts-5.7.4/bin/erlexec
Reading symbols for shared libraries +. done

Program received signal SIGTRAP, Trace/breakpoint trap.
0x00007fff5fc01028 in __dyld__dyld_start ()
(gdb) c
Continuing.
Reading symbols for shared libraries ... done
Erlang R13B03 (erts-5.7.4) [source] [64-bit] [smp:8:8] [rq:8] [async-threads:0] [kernel-poll:false]

Eshell V5.7.4 (abort with ^G)
1>

Filed under: Erlang No Comments
19Aug/091

Getting started with erlbox

Posted by dizzyd

erlbox is a set of Rake tasks that make it easy to build Erlang applications and embedded nodes. It's a framework that Phil and I developed over the past few months and is now something I'd prefer not to live without. While it would be nice to have a "pure" Erlang solution for doing builds, Rake has turned out to be an excellent tool and a reasonable, pragmatic solution to the problem.

Please note that erlbox (and this blog entry) isn't necessarily where you want to start when you're first learning Erlang -- see any of the excellent books for a good introduction to Erlang.

To get started with erlbox, you first need to install Ruby and RubyGems. One you have RubyGems installed, you can then do:

$ gem install erlbox

This should pull down erlbox as well as Rake and any other dependencies. Note that the Debian version of RubyGems is a little weird -- my experience is that using RubyGems from source on Debian yields the best results.

Once you have erlbox installed, you're ready to put together your an Erlang application. In keeping with OTP guidelines, we'll start by creating a standard OTP directory structure:

$ mkdir -p testapp/ebin testapp/src

The next step is to create an application descriptor (ebin/testapp.app) so that Erlang/OTP knows how to start our application up. Drop the following text into testapp/ebin/testapp.app:

{application, testapp,
 [{description, "Test Application"},
  {vsn, "1"},
  {modules, [ testapp,
              testapp_sup ]},
  {registered, []},
  {applications, [kernel,
                  stdlib]},
  {mod, {testapp, []}},
  {env, [
        ]}
 ]}.

The hows/whys of OTP .app files are beyond the scope of this entry -- see the Erlang docs, specifically "Working with OTP/Design Principles" for more details.

With the .app file and the basic directory structure in place, we are now ready to create the Rakefile that will be used by Rake to kick off the erlbox tasks. For this simple build, it's a one-liner:

$ echo "require 'erlbox'" > testapp/Rakefile

We can now use Rake to build our Erlang app:

$ cd testapp; rake
(in /home/dizzyd/src/testapp)
validating testapp.app...
rake aborted!
One or more modules listed in testapp.app do not exist as .beam:
 * testapp
 * testapp_sup

(See full trace by running task with --trace)

As you can see, we still have some work to do. One of the important things that erlbox does is validate the application descriptor ebin/testapp.app and ensure that all the modules it lists are present in compiled form in the ebin/ directory. In this case, the .app file claimed that a module named "testapp" would be present as ebin/testapp.beam, and erlbox generated an error when the module was not found.

So, let's create the source for the testapp module. Drop the following text into testapp/src/testapp.erl:

-module(testapp).

-behaviour(application).

%% Application callbacks
-export([start/2, stop/1]).

%% ===============================================================
%% Application callbacks
%% ===============================================================

start(_StartType, _StartArgs) ->
    testapp_sup:start_link().

stop(_State) ->
    ok.

We also need to define the application supervisor in testapp/src/testapp.erl:

-module(testapp_sup).

-behaviour(supervisor).

%% API
-export([start_link/0]).

%% Supervisor callbacks
-export([init/1]).

%% ===================================================================
%% API functions
%% ===================================================================

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).

%% ===================================================================
%% Supervisor callbacks
%% ===================================================================

init([]) ->
    {ok,{{one_for_one,5,10}, []}}.

The erlbox tasks know to look for all source files in testapp/src/*.erl and compile them to testapp/ebin/*.beam. With these files in place let's try rake again:

$ cd testapp; rake
(in /home/dizzyd/src/testapp)
compiling src/testapp.erl...
compiling src/testapp_sup.erl...
validating testapp.app...
$

The build completed cleanly. Congratulations, you've just built a basic Erlang/OTP application using erlbox.

There are a lot more features in erlbox other than what I've covered here. It also has the ability to build/compile OTP embedded nodes, SNMP MIBs, port drivers and other everyday components that make up the OTP platform.

Filed under: Erlang 1 Comment