|
| 1 | +defmodule LiveDebugger.Services.System.DbgService do |
| 2 | + @moduledoc """ |
| 3 | + This module provides wrappers for system functions that are used for debugging. |
| 4 | + """ |
| 5 | + |
| 6 | + @type port_generator() :: (-> port()) |
| 7 | + @type handler_spec() :: {handler_fun(), initial_data :: term()} |
| 8 | + @type handler_fun() :: (event :: term(), data :: term() -> new_data :: term()) |
| 9 | + @type module_spec() :: |
| 10 | + (-> {tracer_module :: atom(), tracer_state :: term()}) |
| 11 | + | {tracer_module :: atom(), tracer_state :: term()} |
| 12 | + |
| 13 | + @callback tracer(:port, port_generator()) :: {:ok, pid()} | {:error, term()} |
| 14 | + @callback tracer(:process, handler_spec()) :: {:ok, pid()} | {:error, term()} |
| 15 | + @callback tracer(:module, module_spec()) :: {:ok, pid()} | {:error, term()} |
| 16 | + @callback tracer(:file, filename :: :file.name_all()) :: {:ok, pid()} | {:error, term()} |
| 17 | + |
| 18 | + @type match_desc() :: [match_num()] |
| 19 | + @type match_num() :: {:matched, node(), integer()} | {:matched, node(), 0, rPCError :: term()} |
| 20 | + |
| 21 | + @callback p(item :: term(), flags :: term()) :: {:ok, match_desc()} | {:error, term()} |
| 22 | + |
| 23 | + @callback tp(module() | mfa(), match_spec :: term()) :: {:ok, match_desc()} | {:error, term()} |
| 24 | + |
| 25 | + @doc """ |
| 26 | + Wrapper for `:dbg.tracer/2` that starts a tracer for the given type and handler specification. |
| 27 | + """ |
| 28 | + @spec tracer(:port, port_generator()) :: {:ok, pid()} | {:error, term()} |
| 29 | + @spec tracer(:process, handler_spec()) :: {:ok, pid()} | {:error, term()} |
| 30 | + @spec tracer(:module, module_spec()) :: {:ok, pid()} | {:error, term()} |
| 31 | + @spec tracer(:file, filename :: :file.name_all()) :: {:ok, pid()} | {:error, term()} |
| 32 | + def tracer(type, handler_spec) do |
| 33 | + impl().tracer(type, handler_spec) |
| 34 | + end |
| 35 | + |
| 36 | + @doc """ |
| 37 | + Wrapper for `:dbg.p/2`. |
| 38 | + Traces `Item` in accordance to the value specified by `Flags`. |
| 39 | + `p` stands for **p**rocess. |
| 40 | + """ |
| 41 | + @spec p(item :: term(), flags :: term()) :: {:ok, match_desc()} | {:error, term()} |
| 42 | + def p(item, flags) do |
| 43 | + impl().p(item, flags) |
| 44 | + end |
| 45 | + |
| 46 | + @doc """ |
| 47 | + Wrapper for `:dbg.tp/2` that sets up a trace pattern. |
| 48 | + Enables call trace for one or more exported functions specified by `ModuleOrMFA`. |
| 49 | + """ |
| 50 | + @spec tp(module() | mfa(), match_spec :: term()) :: {:ok, match_desc()} | {:error, term()} |
| 51 | + def tp(module, match_spec) do |
| 52 | + impl().tp(module, match_spec) |
| 53 | + end |
| 54 | + |
| 55 | + defp impl() do |
| 56 | + Application.get_env( |
| 57 | + :live_debugger, |
| 58 | + :dbg_service, |
| 59 | + __MODULE__.Impl |
| 60 | + ) |
| 61 | + end |
| 62 | + |
| 63 | + defmodule Impl do |
| 64 | + @moduledoc false |
| 65 | + @behaviour LiveDebugger.Services.System.DbgService |
| 66 | + |
| 67 | + @impl true |
| 68 | + def tracer(type, handler_spec) do |
| 69 | + :dbg.tracer(type, handler_spec) |
| 70 | + end |
| 71 | + |
| 72 | + @impl true |
| 73 | + def p(item, flags) do |
| 74 | + :dbg.p(item, flags) |
| 75 | + end |
| 76 | + |
| 77 | + @impl true |
| 78 | + def tp(module, match_spec) do |
| 79 | + :dbg.tp(module, match_spec) |
| 80 | + end |
| 81 | + end |
| 82 | +end |
0 commit comments