Erlang 21

erl_tracer




erlang

erl_tracer

मॉड्यूल

erl_tracer

मॉड्यूल सारांश

Erlang अनुरेखक व्यवहार।

विवरण

यह व्यवहार मॉड्यूल Erlang अनुरेखण प्रणाली के पीछे के अंत को लागू करता है। जब भी ट्रेस जांच शुरू हो जाती है, तो इस मॉड्यूल के कार्यों को कहा जाता है। ट्रेस जांच को ट्रिगर करने वाली इकाई के संदर्भ में enabled और trace फ़ंक्शन दोनों को बुलाया जाता है। इसका मतलब यह है कि इन कार्यों में कितना समय व्यतीत होता है, इसका पता लगाने में सक्षम होने से ओवरहेड बहुत प्रभावित होता है। इसलिए, इन कार्यों में जितना संभव हो उतना कम काम करें।

ध्यान दें

इस व्यवहार के सभी कार्यों को एनआईएफ के रूप में लागू किया जाना चाहिए। भविष्य के रिलीज में इस सीमा को हटाया जा सकता है। इस पृष्ठ के अंत में एक example tracer module NIF कार्यान्वयन प्रदान किया गया है।

चेतावनी

किसी भी कॉलबैक में संदेश या पोर्ट कमांड को Tracee को न भेजें। यह अनुमति नहीं है और सभी प्रकार के अजीब व्यवहार का कारण बन सकता है, जिसमें शामिल हैं, लेकिन सीमित नहीं, अनंत पुनरावृत्ति।

जानकारी का प्रकार

trace_tag_call() =
call | return_to | return_from | exception_from

trace_tag_gc() =
gc_minor_start | gc_minor_end | gc_major_start | gc_major_end

trace_tag_ports() =
open |
closed |
link |
unlink |
getting_linked |
getting_unlinked

trace_tag_procs() =
spawn |
spawned |
exit |
link |
unlink |
getting_linked |
getting_unlinked |
register |
unregister

trace_tag_receive() = 'receive'
trace_tag_running_ports() =
in | out | in_exiting | out_exiting | out_exited

trace_tag_running_procs() =
in | out | in_exiting | out_exiting | out_exited

trace_tag_send() = send | send_to_non_existing_process

विभिन्न ट्रेस टैग जिन्हें ट्रैसर कहा जाता है। प्रत्येक ट्रेस टैग को Module:trace/5 में विस्तार से वर्णित किया गया है।

tracee() = port() | pid() | undefined

वह प्रक्रिया या पोर्ट जो ट्रेस से संबंधित है।

trace_opts() =
#{extra => term(),
match_spec_result => term(),
scheduler_id => integer() >= 0,
timestamp =>
timestamp | cpu_timestamp | monotonic | strict_monotonic}

ट्रेस के लिए विकल्प:

timestamp
यदि सेट ट्रेसर को टाइम स्टांप शामिल करने का अनुरोध किया गया है।
extra
यदि ट्रेस पॉइंट सेट किया गया है, तो ट्रेस इवेंट के बारे में अतिरिक्त डेटा शामिल किया गया है। अतिरिक्त डेटा क्या है, इस पर निर्भर करता है कि TraceTag को ट्रिगर किया गया है। extra ट्रेस डेटा erlang:trace/3 में वर्णित erlang:trace/3 में पांचवें तत्व से मेल खाती है erlang:trace/3
match_spec_result
यदि ट्रेसर को सेट किए गए मैच विनिर्देश के आउटपुट को शामिल करने का अनुरोध किया गया है।
scheduler_id
यदि अनुसूचक आईडी को अनुरेखक द्वारा शामिल किया जाना है।
tracer_state() = term()

erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) कहते समय निर्दिष्ट की गई स्थिति erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) । अनुरेखक स्थिति एक अपरिवर्तनीय मूल्य है जिसे erl_tracer कॉलबैक में पास किया जाता है और इसमें ट्रेस ईवेंट उत्पन्न करने के लिए आवश्यक सभी डेटा शामिल होते हैं।

कॉलबैक कार्य

निम्नलिखित कार्य एक erl_tracer कॉलबैक मॉड्यूल से निर्यात किए जाने हैं:

Module:enabled/3
अनिवार्य
Module:trace/5
अनिवार्य
Module:enabled_call/3
ऐच्छिक
Module:trace_call/5
ऐच्छिक
Module:enabled_garbage_collection/3
ऐच्छिक
Module:trace_garbage_collection/5
ऐच्छिक
Module:enabled_ports/3
ऐच्छिक
Module:trace_ports/5
ऐच्छिक
Module:enabled_procs/3
ऐच्छिक
Module:trace_procs/5
ऐच्छिक
Module:enabled_receive/3
ऐच्छिक
Module:trace_receive/5
ऐच्छिक
Module:enabled_running_ports/3
ऐच्छिक
Module:trace_running_ports/5
ऐच्छिक
Module:enabled_running_procs/3
ऐच्छिक
Module:trace_running_procs/5
ऐच्छिक
Module:enabled_send/3
ऐच्छिक
Module:trace_send/5
ऐच्छिक

निर्यात

मॉड्यूल: सक्षम (TraceTag, TracerState, Tracee) -> परिणाम

प्रकार

जब भी कोई ट्रेस पॉइंट ट्रिगर होता है तो यह कॉलबैक कहा जाता है। यह ट्रैसर को यह तय करने की अनुमति देता है कि ट्रेस उत्पन्न किया जाना है या नहीं। यह चेक ट्रेसिंग से जुड़े ओवरहेड की मात्रा को सीमित करने के लिए जल्द से जल्द बनाया जाता है। यदि trace वापस किया जाता है, तो आवश्यक ट्रेस डेटा बनाया जाता है और ट्रैसर का ट्रेस कॉलबैक कहा जाता है। यदि discard वापस कर दिया जाता है, तो यह ट्रेस कॉल छोड़ दी जाती है और ट्रेस का कोई कॉल नहीं किया जाता है।

trace_status एक विशेष प्रकार का TraceTag , जिसका उपयोग यह जांचने के लिए किया जाता है कि क्या ट्रेसर अभी भी सक्रिय है। इसे कई परिदृश्यों में कहा जाता है, लेकिन सबसे अधिक इसका उपयोग तब किया जाता है जब इस अनुरेखक का उपयोग करके अनुरेखण शुरू किया जाता है। यदि trace_status की जाँच के बाद हटा दिया जाता है, तो ट्रेसर को ट्रेस से हटा दिया जाता है।

इस फ़ंक्शन को ट्रेसपॉइंट के अनुसार कई बार कहा जा सकता है, इसलिए यह महत्वपूर्ण है कि यह तेज और बिना साइड इफेक्ट दोनों हो।

मॉड्यूल: enable_call (TraceTag, TracerState, Tracee) -> परिणाम

प्रकार

जब भी एक ट्रेसप्वाइंट को ट्रेस फ्लैग erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) साथ कॉलबैक कहा जाता है erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) ट्रिगर है।

यदि enabled_call/3 अपरिभाषित है, तो इसके बजाय Module:enabled/3 enabled_call/3 Module:enabled/3 को कॉल किया जाता है।

मॉड्यूल: enable_garbage_collection (TraceTag, TracerState, Tracee) -> परिणाम

प्रकार

जब भी ट्रेस फ़्लैग erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) साथ एक ट्रेसपॉइंट ट्रिगर erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) है, तो यह कॉलबैक कहा जाता है।

यदि enabled_garbage_collection/3 अपरिभाषित है, तो Module:enabled/3 enabled_garbage_collection/3 को इसके बजाय कहा जाता है।

मॉड्यूल: enable_ports (TraceTag, TracerState, Tracee) -> परिणाम

प्रकार

जब भी ट्रेस ध्वज erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) साथ एक ट्रेस पॉइंट को ट्रिगर किया जाता है, तो यह कॉलबैक कहा जाता है।

अगर enabled_ports/3 अपरिभाषित है, तो Module:enabled/3 enabled_ports/3 को इसके बजाय कहा जाता है।

मॉड्यूल: enable_procs (TraceTag, TracerState, Tracee) -> परिणाम

प्रकार

जब भी ट्रेस फ़्लैग प्रॉक्स के साथ एक ट्रेसपॉइंट ट्रिगर होता है, तो यह कॉलबैक कहा जाता है।

यदि enabled_procs/3 अपरिभाषित है, तो इसके बजाय Module:enabled/3 enabled_procs/3 Module:enabled/3 को कॉल किया जाता है।

मॉड्यूल: enable_receive (TraceTag, TracerState, Tracee) -> परिणाम

प्रकार

जब भी ट्रेसिंग झंडे के साथ erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) तो यह कॉलबैक कहा जाता है।

अगर enabled_receive/3 अपरिभाषित है, तो Module:enabled/3 enabled_receive/3 को इसके बजाय कहा जाता है।

मॉड्यूल: enable_running_ports (TraceTag, TracerState, Tracee) -> परिणाम

प्रकार

जब भी erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) फ्लैग erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) साथ एक ट्रेस erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) को ट्रिगर किया जाता है, तो यह कॉलबैक कहा जाता है।

यदि enabled_running_ports/3 अपरिभाषित है, तो इसके बजाय Module:enabled/3 enabled_running_ports/3 Module:enabled/3 को कॉल किया जाता है।

मॉड्यूल: enable_running_procs (TraceTag, TracerState, Tracee) -> परिणाम

प्रकार

जब भी erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) फ्लैग erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) साथ एक erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) होता है तो यह कॉलबैक कहा जाता है erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) शुरू हो जाता है।

यदि enabled_running_procs/3 अपरिभाषित है, तो इसके बजाय Module:enabled/3 enabled_running_procs/3 Module:enabled/3 को कॉल किया जाता है।

मॉड्यूल: enable_send (TraceTag, TracerState, Tracee) -> परिणाम

प्रकार

जब भी ट्रेस ध्वज erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}]) साथ एक ट्रेसप्वाइंट को ट्रिगर किया जाता है, तो यह कॉलबैक कहा जाता है।

यदि enabled_send/3 अपरिभाषित है, तो Module:enabled/3 enabled_send/3 को इसके बजाय कहा जाता है।

मॉड्यूल: ट्रेस (TraceTag, TracerState, Tracee, TraceTerm, Opts) -> परिणाम

प्रकार

यह कॉलबैक उस समय कहा जाता है जब किसी trace पॉइंट को ट्रिगर किया जाता है और Module:enabled/3 कॉलबैक trace वापस आ जाता trace । इसमें अनुरेखक द्वारा आवश्यक किसी भी दुष्प्रभाव को किया जाना है। TraceTerm पेलोड TraceTerm में स्थित है। TraceTerm की सामग्री इस पर निर्भर करती है कि TraceTag ट्रिगर है। TraceTerm में चौथे तत्व से मेल खाता है erlang:trace/3

यदि टुपल में पांच तत्व हैं, तो पांचवें तत्व को Opts नक्शे में extra मूल्य के रूप में भेजा जाएगा।

मॉड्यूल: ट्रेस (seq_trace, TracerState, Label, SeqTraceInfo, Opts) -> परिणाम

प्रकार

TraceTag seq_trace को थोड़ा अलग seq_trace से संभाला जाता है। seq_trace लिए कोई Tracee नहीं है, इसके बजाय seq_trace इवेंट से संबंधित Label निर्दिष्ट है।

Label और SeqTraceInfo बारे में अधिक जानकारी के लिए, seq_trace(3)

मॉड्यूल: ट्रेस_call (ट्रेसटैग, ट्रेसरस्टेट, ट्रेसी, ट्रेसटर्म, ऑप्स) - परिणाम

प्रकार

यह कॉलबैक उस समय कहा जाता है जब किसी trace Module:enabled_call/3 को ट्रिगर किया जाता है और Module:enabled_call/3 कॉलबैक trace लौटाया जाता trace

यदि trace_call/5 अपरिभाषित है, तो Module:trace/5 को इसके बजाय कहा जाता है।

मॉड्यूल: ट्रेस_गर्ब_कोलेक्शन (ट्रेसटैग, ट्रेसरस्टेट, ट्रेसी, ट्रेसटर्म, ऑप्स) -> परिणाम

प्रकार

यह कॉलबैक उस समय कहा जाता है जब एक trace Module:enabled_garbage_collection/3 ट्रिगर होता है और Module:enabled_garbage_collection/3 कॉलबैक वापस trace

यदि trace_garbage_collection/5 अपरिभाषित है, तो Module:trace/5 को इसके बजाय कहा जाता है।

मॉड्यूल: ट्रेस_पोर्ट्स (TraceTag, TracerState, Tracee, TraceTerm, Opts)> परिणाम

प्रकार

यह कॉलबैक उस समय कहा जाता है जब किसी trace Module:enabled_ports/3 को ट्रिगर किया जाता है और Module:enabled_ports/3 कॉलबैक trace वापस आ जाता trace

यदि trace_ports/5 अपरिभाषित है, तो Module:trace/5 को इसके बजाय कहा जाता है।

मॉड्यूल: ट्रेस_प्रोक्स (ट्रेसटैग, ट्रेसरस्टेट, ट्रेसी, ट्रेसटर्म, ऑप्स) - परिणाम

प्रकार

यह कॉलबैक उस समय कहा जाता है जब किसी trace Module:enabled_procs/3 को ट्रिगर किया जाता है और Module:enabled_procs/3 कॉलबैक trace लौटाया जाता trace

यदि trace_procs/5 अपरिभाषित है, तो Module:trace/5 को इसके बजाय कहा जाता है।

मॉड्यूल: ट्रेस_रेसिव (ट्रेसटैग, ट्रेसरस्टेट, ट्रेसी, ट्रेसटर्म, ऑप्स) -> परिणाम

प्रकार

यह कॉलबैक उस समय कहा जाता है जब किसी trace Module:enabled_receive/3 को ट्रिगर किया जाता है और Module:enabled_receive/3 कॉलबैक trace लौटाया जाता trace

यदि trace_receive/5 अपरिभाषित है, तो Module:trace/5 को इसके बजाय कहा जाता है।

मॉड्यूल: ट्रेस_प्रत्यक्ष_पोर्ट (ट्रेसटैग, ट्रेसरस्टेट, ट्रेसी, ट्रेसटर्म, ऑप्स) -> परिणाम

प्रकार

यह कॉलबैक उस समय कहा जाता है जब एक trace Module:enabled_running_ports/3 को ट्रिगर किया जाता है और Module:enabled_running_ports/3 कॉलबैक वापस trace

यदि trace_running_ports/5 अपरिभाषित है, तो Module:trace/5 को इसके बजाय कहा जाता है।

मॉड्यूल: ट्रेस_प्रत्यक्ष_प्रोक्स (ट्रेसटैग, ट्रेसरस्टेट, ट्रेसी, ट्रेसटर्म, ऑप्स) -> परिणाम

प्रकार

यह कॉलबैक उस समय कहा जाता है जब किसी trace Module:enabled_running_procs/3 को ट्रिगर किया जाता है और Module:enabled_running_procs/3 कॉलबैक trace लौटाया जाता trace

यदि trace_running_procs/5 अपरिभाषित है, तो Module:trace/5 को इसके बजाय कहा जाता है।

मॉड्यूल: ट्रेस_सेंड (ट्रेसटैग, ट्रेसरस्टेट, ट्रेसी, ट्रेसटर्म, ऑप्स) - परिणाम

प्रकार

यह कॉलबैक उस समय कहा जाता है जब किसी trace Module:enabled_send/3 को ट्रिगर किया जाता है और Module:enabled_send/3 कॉलबैक trace लौटाया जाता trace

यदि trace_send/5 अपरिभाषित है, तो Module:trace/5 को इसके बजाय कहा जाता है।

एर्ल ट्रेसर मॉड्यूल उदाहरण

इस उदाहरण में, NIF बैक एंड के साथ एक ट्रैसर मॉड्यूल प्रत्येक send ट्रेस टैग के लिए एक संदेश भेजता है जिसमें केवल प्रेषक और रिसीवर होता है। इस ट्रैसर मॉड्यूल का उपयोग करते हुए, बहुत अधिक हल्के संदेश ट्रैसर का उपयोग किया जाता है, जो केवल रिकॉर्ड करता है कि किसने संदेश भेजे।

निम्नलिखित लिनक्स पर इसका उपयोग करने वाला एक उदाहरण सत्र है:

$ gcc -I erts-8.0/include/ -fPIC -shared -o erl_msg_tracer.so erl_msg_tracer.c
$ erl
Erlang/OTP 19 [DEVELOPMENT] [erts-8.0] [source-ed2b56b] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V8.0  (abort with ^G)
1> c(erl_msg_tracer), erl_msg_tracer:load().
ok
2> Tracer = spawn(fun F() -> receive M -> io:format("~p~n",[M]), F() end end).
<0.37.0>
3> erlang:trace(new, true, [send,{tracer, erl_msg_tracer, Tracer}]).
0
{trace,<0.39.0>,<0.27.0>}
4> {ok, D} = file:open("/tmp/tmp.data",[write]).
{trace,#Port<0.486>,<0.40.0>}
{trace,<0.40.0>,<0.21.0>}
{trace,#Port<0.487>,<0.4.0>}
{trace,#Port<0.488>,<0.4.0>}
{trace,#Port<0.489>,<0.4.0>}
{trace,#Port<0.490>,<0.4.0>}
{ok,<0.40.0>}
{trace,<0.41.0>,<0.27.0>}
5>

erl_msg_tracer.erl :

-module(erl_msg_tracer).

-export([enabled/3, trace/5, load/0]).

load() ->
    erlang:load_nif("erl_msg_tracer", []).

enabled(_, _, _) ->
    error.

trace(_, _, _, _, _) ->
    error.

erl_msg_tracer.c :

#include <erl_nif.h>

/* NIF interface declarations */
static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info);
static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info);
static void unload(ErlNifEnv* env, void* priv_data);

/* The NIFs: */
static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);

static ErlNifFunc nif_funcs[] = {
    {"enabled", 3, enabled},
    {"trace", 5, trace}
};

ERL_NIF_INIT(erl_msg_tracer, nif_funcs, load, NULL, upgrade, unload)

static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
    *priv_data = NULL;
    return 0;
}

static void unload(ErlNifEnv* env, void* priv_data)
{

}

static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data,
		   ERL_NIF_TERM load_info)
{
    if (*old_priv_data != NULL || *priv_data != NULL) {
	return -1; /* Don't know how to do that */
    }
    if (load(env, priv_data, load_info)) {
	return -1;
    }
    return 0;
}

/*
 * argv[0]: TraceTag
 * argv[1]: TracerState
 * argv[2]: Tracee
 */
static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifPid to_pid;
    if (enif_get_local_pid(env, argv[1], &to_pid))
        if (!enif_is_process_alive(env, &to_pid))
            if (enif_is_identical(enif_make_atom(env, "trace_status"), argv[0]))
                /* tracer is dead so we should remove this tracepoint */
                return enif_make_atom(env, "remove");
            else
                return enif_make_atom(env, "discard");

    /* Only generate trace for when tracer != tracee */
    if (enif_is_identical(argv[1], argv[2]))
        return enif_make_atom(env, "discard");

    /* Only trigger trace messages on 'send' */
    if (enif_is_identical(enif_make_atom(env, "send"), argv[0]))
        return enif_make_atom(env, "trace");

    /* Have to answer trace_status */
    if (enif_is_identical(enif_make_atom(env, "trace_status"), argv[0]))
        return enif_make_atom(env, "trace");

    return enif_make_atom(env, "discard");
}

/*
 * argv[0]: TraceTag, should only be 'send'
 * argv[1]: TracerState, process to send {Tracee, Recipient} to
 * argv[2]: Tracee
 * argv[3]: Message
 * argv[4]: Options, map containing Recipient
 */
static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifPid to_pid;
    ERL_NIF_TERM recipient, msg;

    if (enif_get_local_pid(env, argv[1], &to_pid)) {
      if (enif_get_map_value(env, argv[4], enif_make_atom(env, "extra"), &recipient)) {
        msg = enif_make_tuple3(env, enif_make_atom(env, "trace"), argv[2], recipient);
        enif_send(env, &to_pid, NULL, msg);
      }
    }

    return enif_make_atom(env, "ok");
}