Dbg and match specs - how much nesting is too much?

From this:

If a match specification passed as argument has excessive nesting which causes scheduler stack exhaustion for the scheduler that the calling process is executing on. Scheduler stack size can be can be configured when starting the runtime system

Exactly how much nesting is too much? I have a plan to do a lengthy debug session and the match specs could get pretty gnarly. The match specs will be applied, but only a handful of processes will be traced at any time and most of those will be short lived. . We will id them, do dbg.p let them be traced for a few seconds and when they have done their work they either terminate or disable tracing and go to sleep.

Worse case example, and if there is a cleaner way to do what’s below please let me know :grinning: … can I just apply each rule at a time?

{:orelse,
{:orelse,
{:orelse,
{:orelse,
{:orelse,
{:orelse,
{:orelse,
{:orelse,
{:orelse,
{:orelse,
{:andalso, {:==, :“$1”, “PUT”},
{:==, {:binary_part, :“$2”, 0, 17}, “/users/approvals/”}},
{:andalso, {:==, :“$1”, “POST”},
{:andalso, {:==, {:binary_part, :“$2”, 0, 12}, “/users/orgs/”},
{:==, {:binary_part, :“$2”, 48, 21}, “/submit_export_shards”}}}},
{:andalso, {:==, :“$1”, “GET”},
{:andalso, {:==, {:binary_part, :“$2”, 0, 8}, “/export/”},
{:==, {:binary_part, :“$2”, 44, 13}, “/group/shards”}}}},
{:andalso, {:==, :“$1”, “POST”},
{:==, {:binary_part, :“$2”, 0, 13}, “/users/events”}}},
{:andalso, {:==, :“$1”, “PATCH”},
{:==, {:binary_part, :“$2”, 0, 12}, “/users/orgs/”}}},
{:andalso, {:==, :“$1”, “GET”},
{:==, {:binary_part, :“$2”, 0, 22}, “/users/approvers/shard”}}},
{:andalso, {:==, :“$1”, “PUT”},
{:==, {:binary_part, :“$2”, 0, 14}, “/users/events/”}}},
{:andalso, {:==, :“$1”, “GET”},
{:==, {:binary_part, :“$2”, 0, 13}, “/users/events”}}},
{:andalso, {:==, :“$1”, “POST”},
{:==, {:binary_part, :“$2”, 0, 15}, “/users/requests”}}},
{:andalso, {:==, :“$1”, “PUT”}, {:==, {:binary_part, :“$2”, 0, 6}, “/users”}}},
{:andalso, {:==, :“$1”, “GET”},
{:==, {:binary_part, :“$2”, 0, 16}, “/users/approvals”}}}

1 Like

I’d be tempted to filter the debugging events in the tracer function.

I wrote it up here: Debugging gen_server timeouts | Roger's Blog

But, essentially:

dbg:tracer(process, {TFun, TState0}).
dbg:tpl(Mod, Fun, '_', dbg:fun2ms(fun(_) -> return_trace() end)).

Note that I’m using a trivial match-spec.

Then do the filtering in the trace function:

TFun =
    fun(_Msg =
        {trace, _Pid, call,
            {Mod, Fun, _Args = ["POST", <<"/users/events", _/binary>> | _]}},
        TState) ->
            % something interesting; don't forget the other function clauses.
    end.

I’m not sure this entirely fits your use-case, but it’s a useful trick.

I do a little bit of pattern matching like that. The problem is the APIs change frequently, and I don’t want to have to update the tracer/dbg code all the time. As it is I can generate the Erlang match spec from swagger specifications dynamically.