new stack backtrace

Martin Bjorklund <>
Tue Dec 14 10:38:20 CET 1999


The new stack backtrace printout on failures is great!  But I just
spent half an hour trying to find out what was wrong with the
following function in the module 'bt_conf':


init_gws(Node) ->
    Cf  = bt_cmd:bgetconfig(Node, cluster),
    Gws =
	foldl(
	  fun({_, "FrontendCluster", _, Vs}, Gws1) ->
		  foldl(
		    fun({_,Gw,[SNd, Ip, SPort, Profile],_},Gws2) ->
			    Nd = list_to_atom(SNd),
			    Port = list_to_integer(SPort),
			    [{to_proto(Gw), Nd, Ip, Port, Profile} | Gws2];
		       (_, Gws2) ->
			    Gws2
		    end, Gws1, Vs);
	     (_, Gws1) ->
		  Gws1
	  end, [], Cf),
    GwRs = collect(Gws),
    foreach(fun(GwR) -> ets:insert(bt_tab, {{gw, GwR#bt_gw.protocol}, GwR}) end,
	    GwRs).


... after I got this crash:

    error_info: {undef,[{config_file,parse_string,["sh: /home...\n"]},
                        {bt_conf,init_gws,1},
                        {bt_conf,init_tab,1},
                        {btest,init_server,1},
                        {proc_lib,init_p,5}]}


First of all, the stacktrace suggests that bt_conf calls
config_file:parse_string, which crashes with the reason 'undef'.  But
the top entry on the stack look suspicious; the argument list is
printed, not the arity.  Thus, I thought that bt_conf calls the
undefined function confgi_file:parse_string (a look in
error_handler.erl confirms this, more about this below).

Obviously, I have no calls to config_file:parse_string in
init_gws/1, as indicated by the backtrace.  But, init_gws calls
bt_cmd:get_config, which looks like this:

bgetconfig(Node, Type) ->
    Cmd = cmd("bgetconfig"),
    ibgetconfig(Cmd ++ " -t " ++ atom_to_list(Type) ++ " " ++
		atom_to_list(Node)).

ibgetconfig(Cmd) ->
    Res = os:cmd(Cmd),
    config_file:parse_string(Res).


... and there's the error.


The first question is why these last two calls don't show up in the
stack backtrace?

The second question is why the backtrace looks like it does; in
earlier releases the undef EXIT looked like this:
  {'EXIT',{undef,{Module,Function,Args}}}

Wouldn't it be more consistent with the other exit reasons to use
this format in the new release too, i.e. change error_handler:crash
from:

crash(MFA) ->
    {'EXIT',{undef,[Current|Mfas]}} = (catch erlang:fault(undef)),
    exit({undef,[MFA|Mfas]}).

to:

crash(MFA) ->
    {'EXIT',{undef,[Current|Mfas]}} = (catch erlang:fault(undef)),
    exit({{undef, MFA},Mfas}).



/martin



More information about the erlang-questions mailing list