aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/beam/erl_trace.c2
-rw-r--r--lib/runtime_tools/c_src/dyntrace.c94
-rw-r--r--lib/runtime_tools/c_src/dyntrace_lttng.h89
3 files changed, 172 insertions, 13 deletions
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 96fc46c817..fa1d03c588 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -1294,7 +1294,7 @@ trace_proc_spawn(Process *p, Eterm what, Eterm pid,
mfa = TUPLE3(hp, mod, func, args);
hp += 4;
send_to_tracer_nif(p, &p->common, p->common.id, tnif, TRACE_FUN_PROCS,
- am_spawn, pid, mfa);
+ what, pid, mfa);
}
}
diff --git a/lib/runtime_tools/c_src/dyntrace.c b/lib/runtime_tools/c_src/dyntrace.c
index 6344f6ed90..3da003f281 100644
--- a/lib/runtime_tools/c_src/dyntrace.c
+++ b/lib/runtime_tools/c_src/dyntrace.c
@@ -105,6 +105,17 @@ static ERL_NIF_TERM atom_discard;
static ERL_NIF_TERM atom_gc_start;
static ERL_NIF_TERM atom_gc_end;
+/* process atoms */
+
+static ERL_NIF_TERM atom_spawn;
+static ERL_NIF_TERM atom_exit;
+static ERL_NIF_TERM atom_register;
+static ERL_NIF_TERM atom_unregister;
+static ERL_NIF_TERM atom_link;
+static ERL_NIF_TERM atom_unlink;
+static ERL_NIF_TERM atom_getting_linked;
+static ERL_NIF_TERM atom_getting_unlinked;
+
static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
@@ -119,9 +130,22 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
atom_remove = enif_make_atom(env,"remove");
atom_discard = enif_make_atom(env,"discard");
+ /* gc */
+
atom_gc_start = enif_make_atom(env,"gc_start");
atom_gc_end = enif_make_atom(env,"gc_end");
+ /* process 'proc' */
+
+ atom_spawn = enif_make_atom(env,"spawn");
+ atom_exit = enif_make_atom(env,"exit");
+ atom_register = enif_make_atom(env,"register");
+ atom_unregister = enif_make_atom(env,"unregister");
+ atom_link = enif_make_atom(env,"link");
+ atom_unlink = enif_make_atom(env,"unlink");
+ atom_getting_unlinked = enif_make_atom(env,"getting_unlinked");
+ atom_getting_linked = enif_make_atom(env,"getting_linked");
+
return 0;
}
@@ -176,13 +200,6 @@ static ERL_NIF_TERM enabled(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
return atom_trace;
#elif HAVE_USE_LTTNG
- /*
- int i;
- erts_fprintf(stderr, "enabled:\r\n");
- for (i = 0; i < argc; i++) {
- erts_fprintf(stderr, " %T\r\n", argv[i]);
- }
- */
return atom_trace;
#endif
return atom_remove;
@@ -239,6 +256,8 @@ static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
#endif
return atom_ok;
}
+
+
static ERL_NIF_TERM trace_garbage_collection(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
#ifdef HAVE_USE_DTRACE
@@ -411,10 +430,63 @@ static ERL_NIF_TERM trace_procs(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
}
#elif HAVE_USE_LTTNG
- int i;
- erts_fprintf(stderr, "trace:\r\n");
- for (i = 0; i < argc; i++) {
- erts_fprintf(stderr, " %T\r\n", argv[i]);
+ lttng_decl_procbuf(pid);
+ lttng_decl_procbuf(to);
+
+ lttng_pid_to_str(argv[2], pid);
+
+ /* spawn */
+ if (argv[0] == atom_spawn) {
+ char undef[] = "undefined";
+ const ERL_NIF_TERM* tuple;
+ int arity;
+ unsigned int len;
+ lttng_decl_mfabuf(mfa);
+
+ lttng_pid_to_str(argv[3], to);
+
+ if (enif_get_tuple(env, argv[4], &arity, &tuple)) {
+ enif_get_list_length(env, tuple[2], &len);
+ lttng_mfa_to_str(tuple[0], tuple[1], len, mfa);
+ LTTNG3(process_spawn, to, pid, mfa);
+ } else {
+ LTTNG3(process_spawn, to, pid, undef);
+ }
+
+ /* register */
+ } else if (argv[0] == atom_register) {
+ char name[LTTNG_BUFFER_SZ];
+ erts_snprintf(name, LTTNG_BUFFER_SZ, "%T", argv[3]);
+ LTTNG3(process_register, pid, name, "register");
+ } else if (argv[0] == atom_unregister) {
+ char name[LTTNG_BUFFER_SZ];
+ erts_snprintf(name, LTTNG_BUFFER_SZ, "%T", argv[3]);
+ LTTNG3(process_register, pid, name, "unregister");
+ /* link */
+ } else if (argv[0] == atom_link) {
+ lttng_pid_to_str(argv[3], to);
+ LTTNG3(process_link, pid, to, "link");
+ /* link */
+ } else if (argv[0] == atom_unlink) {
+ lttng_pid_to_str(argv[3], to);
+ LTTNG3(process_link, pid, to, "unlink");
+ } else if (argv[0] == atom_getting_linked) {
+ lttng_pid_to_str(argv[3], to);
+ LTTNG3(process_link, to, pid, "link");
+ } else if (argv[0] == atom_getting_unlinked) {
+ lttng_pid_to_str(argv[3], to);
+ LTTNG3(process_link, to, pid, "unlink");
+ /* exit */
+ } else if (argv[0] == atom_exit) {
+ char reason[LTTNG_BUFFER_SZ];
+ erts_snprintf(reason, LTTNG_BUFFER_SZ, "%T", argv[3]);
+ LTTNG2(process_exit, pid, reason);
+ } else {
+ int i;
+ erts_fprintf(stderr, "trace:\r\n");
+ for (i = 0; i < argc; i++) {
+ erts_fprintf(stderr, " %T\r\n", argv[i]);
+ }
}
#endif
return atom_ok;
diff --git a/lib/runtime_tools/c_src/dyntrace_lttng.h b/lib/runtime_tools/c_src/dyntrace_lttng.h
index e4482675bf..c2fd003d48 100644
--- a/lib/runtime_tools/c_src/dyntrace_lttng.h
+++ b/lib/runtime_tools/c_src/dyntrace_lttng.h
@@ -26,7 +26,6 @@
#include <lttng/tracepoint.h>
-/* include a special LTTNG_DO for do_tracepoint ? */
#define LTTNG1(Name, Arg1) \
tracepoint(com_ericsson_dyntrace, Name, (Arg1))
@@ -42,6 +41,94 @@
#define LTTNG5(Name, Arg1, Arg2, Arg3, Arg4, Arg5) \
tracepoint(com_ericsson_dyntrace, Name, (Arg1), (Arg2), (Arg3), (Arg4), (Arg5))
+#define LTTNG_BUFFER_SZ (256)
+#define LTTNG_PROC_BUFFER_SZ (16)
+#define LTTNG_PORT_BUFFER_SZ (20)
+#define LTTNG_MFA_BUFFER_SZ (256)
+
+#define lttng_decl_procbuf(Name) \
+ char Name[LTTNG_PROC_BUFFER_SZ]
+
+#define lttng_decl_portbuf(Name) \
+ char Name[LTTNG_PORT_BUFFER_SZ]
+
+#define lttng_decl_mfabuf(Name) \
+ char Name[LTTNG_MFA_BUFFER_SZ]
+
+#define lttng_pid_to_str(pid, name) \
+ erts_snprintf(name, LTTNG_PROC_BUFFER_SZ, "%T", (pid))
+
+#define lttng_portid_to_str(pid, name) \
+ erts_snprintf(name, LTTNG_PORT_BUFFER_SZ, "%T", (pid))
+
+#define lttng_proc_to_str(p, name) \
+ lttng_pid_to_str(((p) ? (p)->common.id : ERTS_INVALID_PID), name)
+
+#define lttng_port_to_str(p, name) \
+ lttng_portid_to_str(((p) ? (p)->common.id : ERTS_INVALID_PORT), name)
+
+#define lttng_mfa_to_str(m,f,a, Name) \
+ erts_snprintf(Name, LTTNG_MFA_BUFFER_SZ, "%T:%T/%lu", (Eterm)(m), (Eterm)(f), (Uint)(a))
+
+/* Process scheduling */
+
+TRACEPOINT_EVENT(
+ com_ericsson_dyntrace,
+ process_spawn,
+ TP_ARGS(
+ char*, p,
+ char*, parent,
+ char*, mfa
+ ),
+ TP_FIELDS(
+ ctf_string(pid, p)
+ ctf_string(parent, parent)
+ ctf_string(entry, mfa)
+ )
+)
+
+TRACEPOINT_EVENT(
+ com_ericsson_dyntrace,
+ process_link,
+ TP_ARGS(
+ char*, from,
+ char*, to,
+ char*, type
+ ),
+ TP_FIELDS(
+ ctf_string(from, from)
+ ctf_string(to, to)
+ ctf_string(type, type)
+ )
+)
+
+TRACEPOINT_EVENT(
+ com_ericsson_dyntrace,
+ process_exit,
+ TP_ARGS(
+ char*, p,
+ char*, reason
+ ),
+ TP_FIELDS(
+ ctf_string(pid, p)
+ ctf_string(reason, reason)
+ )
+)
+
+TRACEPOINT_EVENT(
+ com_ericsson_dyntrace,
+ process_register,
+ TP_ARGS(
+ char*, pid,
+ char*, name,
+ char*, type
+ ),
+ TP_FIELDS(
+ ctf_string(pid, pid)
+ ctf_string(name, name)
+ ctf_string(type, type)
+ )
+)
/* Process Memory */