From cc290266f06458c8009182167418ef9f1e21a794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Thu, 3 Mar 2016 15:14:03 +0100 Subject: runtime_tools: Add lttng 'ports' tracing --- lib/runtime_tools/c_src/dyntrace.c | 58 ++++++++++++++++++++++++++++++++ lib/runtime_tools/c_src/dyntrace_lttng.h | 47 ++++++++++++++++++++++++++ lib/runtime_tools/src/dyntrace.erl | 6 ++++ 3 files changed, 111 insertions(+) diff --git a/lib/runtime_tools/c_src/dyntrace.c b/lib/runtime_tools/c_src/dyntrace.c index 0be72848e6..43d61266cc 100644 --- a/lib/runtime_tools/c_src/dyntrace.c +++ b/lib/runtime_tools/c_src/dyntrace.c @@ -69,6 +69,7 @@ static ERL_NIF_TERM user_trace_n(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar 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 ERL_NIF_TERM trace_procs(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM trace_ports(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM trace_running(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM trace_send(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM trace_receive(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); @@ -83,6 +84,7 @@ static ErlNifFunc nif_funcs[] = { {"trace", 5, trace}, {"trace", 6, trace}, {"trace_procs", 6, trace_procs}, + {"trace_ports", 6, trace_ports}, {"trace_running", 6, trace_running}, {"trace_send", 6, trace_send}, {"trace_receive", 6, trace_receive}, @@ -132,6 +134,10 @@ static ERL_NIF_TERM atom_send; static ERL_NIF_TERM atom_receive; static ERL_NIF_TERM atom_send_to_non_existing_process; +/* ports 'ports' */ + +static ERL_NIF_TERM atom_open; +static ERL_NIF_TERM atom_closed; static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) { @@ -176,6 +182,11 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) atom_receive = enif_make_atom(env,"receive"); atom_send_to_non_existing_process = enif_make_atom(env,"send_to_non_existing_process"); + /* ports 'ports' */ + + atom_open = enif_make_atom(env,"open"); + atom_closed = enif_make_atom(env,"closed"); + return 0; } @@ -475,6 +486,53 @@ static ERL_NIF_TERM trace_procs(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg return atom_ok; } +static ERL_NIF_TERM trace_ports(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ +#ifdef HAVE_USE_DTRACE +#elif HAVE_USE_LTTNG + lttng_decl_portbuf(port); + lttng_decl_procbuf(to); + + lttng_portid_to_str(argv[2], port); + + /* open and closed */ + if (argv[0] == atom_open) { + char driver[LTTNG_BUFFER_SZ]; + lttng_decl_procbuf(pid); + lttng_pid_to_str(argv[3], pid); + + erts_snprintf(driver, LTTNG_BUFFER_SZ, "%T", argv[4]); + LTTNG3(port_open, pid, driver, port); + } else if (argv[0] == atom_closed) { + char reason[LTTNG_BUFFER_SZ]; + erts_snprintf(reason, LTTNG_BUFFER_SZ, "%T", argv[3]); + + LTTNG2(port_exit, port, reason); + /* link */ + } else if (argv[0] == atom_link) { + lttng_pid_to_str(argv[3], to); + LTTNG3(port_link, port, to, "link"); + } else if (argv[0] == atom_unlink) { + lttng_pid_to_str(argv[3], to); + LTTNG3(port_link, port, to, "unlink"); + } else if (argv[0] == atom_getting_linked) { + lttng_pid_to_str(argv[3], to); + LTTNG3(port_link, to, port, "link"); + } else if (argv[0] == atom_getting_unlinked) { + lttng_pid_to_str(argv[3], to); + LTTNG3(port_link, to, port, "unlink"); + } else { + int i; + erts_fprintf(stderr, "ports trace:\r\n"); + for (i = 0; i < argc; i++) { + erts_fprintf(stderr, " %T\r\n", argv[i]); + } + } +#endif + return atom_ok; +} + + static ERL_NIF_TERM trace_running(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { #ifdef HAVE_USE_DTRACE diff --git a/lib/runtime_tools/c_src/dyntrace_lttng.h b/lib/runtime_tools/c_src/dyntrace_lttng.h index 03cf8a27c1..2e0b921621 100644 --- a/lib/runtime_tools/c_src/dyntrace_lttng.h +++ b/lib/runtime_tools/c_src/dyntrace_lttng.h @@ -147,6 +147,53 @@ TRACEPOINT_EVENT( ) ) +/* Ports */ + + +TRACEPOINT_EVENT( + com_ericsson_dyntrace, + port_open, + TP_ARGS( + char*, pid, + char*, driver, + char*, port + ), + TP_FIELDS( + ctf_string(pid, pid) + ctf_string(driver, driver) + ctf_string(port, port) + ) +) + +TRACEPOINT_EVENT( + com_ericsson_dyntrace, + port_exit, + TP_ARGS( + char*, port, + char*, reason + ), + TP_FIELDS( + ctf_string(port, port) + ctf_string(reason, reason) + ) +) + +TRACEPOINT_EVENT( + com_ericsson_dyntrace, + port_link, + TP_ARGS( + char*, from, + char*, to, + char*, type + ), + TP_FIELDS( + ctf_string(from, from) + ctf_string(to, to) + ctf_string(type, type) + ) +) + + /* Process messages */ TRACEPOINT_EVENT( diff --git a/lib/runtime_tools/src/dyntrace.erl b/lib/runtime_tools/src/dyntrace.erl index aef4d9fab0..44c5e36242 100644 --- a/lib/runtime_tools/src/dyntrace.erl +++ b/lib/runtime_tools/src/dyntrace.erl @@ -45,6 +45,7 @@ trace/5, trace/6, trace_procs/6, + trace_ports/6, trace_running/6, trace_send/6, trace_receive/6, @@ -147,13 +148,18 @@ trace(_TraceTag, _TracerState, _Tracee, _FirstTraceTerm, _SecondTraceTerm, _Opts trace_procs(_TraceTag, _TracerState, _Tracee, _FirstTraceTerm, _SecondTraceTerm, _Opts) -> erlang:nif_error(nif_not_loaded). +trace_ports(_TraceTag, _TracerState, _Tracee, _FirstTraceTerm, _SecondTraceTerm, _Opts) -> + erlang:nif_error(nif_not_loaded). + trace_running(_TraceTag, _TracerState, _Tracee, _FirstTraceTerm, _SecondTraceTerm, _Opts) -> erlang:nif_error(nif_not_loaded). trace_send(_TraceTag, _TracerState, _Tracee, _FirstTraceTerm, _SecondTraceTerm, _Opts) -> erlang:nif_error(nif_not_loaded). + trace_receive(_TraceTag, _TracerState, _Tracee, _FirstTraceTerm, _SecondTraceTerm, _Opts) -> erlang:nif_error(nif_not_loaded). + trace_garbage_collection(_TraceTag, _TracerState, _Tracee, _FirstTraceTerm, _SecondTraceTerm, _Opts) -> erlang:nif_error(nif_not_loaded). -- cgit v1.2.3