Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: erlang/otp
base: maint
...
head fork: softlab-ntua/dtrace-percept
compare: maint
Checking mergeability… Don't worry, you can still create the pull request.
  • 7 commits
  • 12 files changed
  • 0 commit comments
  • 1 contributor
View
41 README.dtrace-percept.md
@@ -0,0 +1,41 @@
+# What is DTrace Percept?
+
+A back-end for Percept that is based on DTrace rather than on the built-in
+tracing machanisms of Erlang for the collection of trace information.
+
+# How can I use DTrace Percept?
+
+Run the DTrace/SystemTap script and redirect its output into a file.
+
+ stap path/to/percept/lib/priv/dtrace/dtrace-percept.stap > trace.dat
+
+ dtrace path/to/percept/lib/priv/dtrace/dtrace-percept.d > trace.dat
+
+Perform the action you want to trace.
+
+ erl -noshell - eval "bang:bang(2,30)." -s init stop
+
+Stop the execution of the DTrace/SystemTap script (by pressing Ctrl+C).
+
+Analyze the produced trace file.
+
+ 1> percept:d_analyze("trace.dat").
+
+Start the web server (as usual) and inspect the collected information using
+your favorite browser (as usual).
+
+ 1> percept:start_webserver().
+
+
+# What is the current status of DTrace Percept?
+
+Currently, the DTrace back-end of Percept traces specific events (spawn, link,
+getting unlinked, exit, active/inactive).
+
+The back-end does not expose any flags that can be set, so that the user can
+specify the pieces of trace information that should be collected.
+
+DTrace back-end can collect information only from Erlang VM's that are started
+after the execution of the DTrace/SystemTap script, and not from already
+running Erlang VM's.
+
View
30 erts/emulator/beam/bif.c
@@ -121,6 +121,9 @@ static int insert_internal_link(Process* p, Eterm rpid)
}
if (IS_TRACED_FL(rp, F_TRACE_PROCS))
trace_proc(p, rp, am_getting_linked, p->id);
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc(p, rp, am_getting_linked, p->id);
+ }
if (p == rp)
erts_smp_proc_unlock(p, rp_locks & ~ERTS_PROC_LOCK_MAIN);
@@ -141,6 +144,9 @@ BIF_RETTYPE link_1(BIF_ALIST_1)
if (IS_TRACED_FL(BIF_P, F_TRACE_PROCS)) {
trace_proc(BIF_P, BIF_P, am_link, BIF_ARG_1);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc(BIF_P, BIF_P, am_link, BIF_ARG_1);
+ }
/* check that the pid or port which is our argument is OK */
if (is_internal_pid(BIF_ARG_1)) {
@@ -937,6 +943,9 @@ BIF_RETTYPE unlink_1(BIF_ALIST_1)
if (IS_TRACED_FL(BIF_P, F_TRACE_PROCS)) {
trace_proc(BIF_P, BIF_P, am_unlink, BIF_ARG_1);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc(BIF_P, BIF_P, am_unlink, BIF_ARG_1);
+ }
if (is_internal_port(BIF_ARG_1)) {
Port *pt = erts_id2port_sflgs(BIF_ARG_1,
@@ -1072,6 +1081,9 @@ BIF_RETTYPE unlink_1(BIF_ALIST_1)
if (IS_TRACED_FL(rp, F_TRACE_PROCS) && rl != NULL) {
trace_proc(BIF_P, rp, am_getting_unlinked, BIF_P->id);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc(BIF_P, rp, am_getting_unlinked, BIF_P->id);
+ }
if (rp != BIF_P)
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK);
@@ -1863,6 +1875,9 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend) {
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(p, am_inactive);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(p, am_inactive);
+ }
erts_whereis_name(p, ERTS_PROC_LOCK_MAIN,
to,
&rp, 0, ERTS_P2P_FLG_SMP_INC_REFC,
@@ -1880,6 +1895,9 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend) {
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(p, am_active);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(p, am_active);
+ }
if (IS_TRACED(p))
trace_send(p, to, msg);
@@ -1912,6 +1930,9 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend) {
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(p, am_inactive);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(p, am_inactive);
+ }
pt = erts_id2port(to, p, ERTS_PROC_LOCK_MAIN);
port_common:
ERTS_SMP_LC_ASSERT(!pt || erts_lc_is_port_locked(pt));
@@ -1977,6 +1998,9 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend) {
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(p, am_active);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(p, am_active);
+ }
if (ERTS_PROC_IS_EXITING(p)) {
KILL_CATCHES(p); /* Must exit */
return SEND_USER_ERROR;
@@ -2014,6 +2038,9 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend) {
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(p, am_inactive);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(p, am_inactive);
+ }
erts_whereis_name(p, ERTS_PROC_LOCK_MAIN,
tp[1],
@@ -2033,6 +2060,9 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend) {
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(p, am_active);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(p, am_active);
+ }
if (!rp) {
return 0;
View
12 erts/emulator/beam/dist.c
@@ -327,6 +327,9 @@ static void doit_link_net_exits_sub(ErtsLink *sublnk, void *vlnecp)
/* We didn't exit the process and it is traced */
trace_proc(NULL, rp, am_getting_unlinked, sublnk->pid);
}
+ if (xres >= 0 && DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc(NULL, rp, am_getting_unlinked, sublnk->pid);
+ }
}
erts_smp_proc_unlock(rp, rp_locks);
}
@@ -1155,6 +1158,9 @@ int erts_net_message(Port *prt,
if (IS_TRACED_FL(rp, F_TRACE_PROCS))
trace_proc(NULL, rp, am_getting_linked, from);
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc(NULL, rp, am_getting_linked, from);
+ }
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK);
break;
@@ -1181,6 +1187,9 @@ int erts_net_message(Port *prt,
if (IS_TRACED_FL(rp, F_TRACE_PROCS) && lnk != NULL) {
trace_proc(NULL, rp, am_getting_unlinked, from);
}
+ if (DTRACE_ENABLED(percept_trace) && lnk != NULL) {
+ d_trace_proc(NULL, rp, am_getting_unlinked, from);
+ }
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK);
@@ -1511,6 +1520,9 @@ int erts_net_message(Port *prt,
/* We didn't exit the process and it is traced */
trace_proc(NULL, rp, am_getting_unlinked, from);
}
+ if (xres >= 0 && DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc(NULL, rp, am_getting_unlinked, from);
+ }
}
erts_smp_proc_unlock(rp, rp_locks);
}
View
29 erts/emulator/beam/erl_bif_port.c
@@ -136,6 +136,9 @@ do_port_command(Process *BIF_P, Eterm arg1, Eterm arg2, Eterm arg3,
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(BIF_P, am_inactive);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(BIF_P, am_inactive);
+ }
p = id_or_name2port(BIF_P, arg1);
if (!p) {
@@ -145,6 +148,9 @@ do_port_command(Process *BIF_P, Eterm arg1, Eterm arg2, Eterm arg3,
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(BIF_P, am_active);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(BIF_P, am_active);
+ }
BIF_ERROR(BIF_P, BADARG);
}
@@ -202,6 +208,9 @@ do_port_command(Process *BIF_P, Eterm arg1, Eterm arg2, Eterm arg3,
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(BIF_P, am_active);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(BIF_P, am_active);
+ }
if (ERTS_PROC_IS_EXITING(BIF_P)) {
KILL_CATCHES(BIF_P); /* Must exit */
@@ -281,6 +290,9 @@ port_call(Process* c_p, Eterm arg1, Eterm arg2, Eterm arg3)
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(c_p, am_inactive);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(c_p, am_inactive);
+ }
p = id_or_name2port(c_p, arg1);
if (!p) {
@@ -301,6 +313,9 @@ port_call(Process* c_p, Eterm arg1, Eterm arg2, Eterm arg3)
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(c_p, am_active);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(c_p, am_active);
+ }
if (p)
erts_port_release(p);
@@ -427,7 +442,10 @@ port_call(Process* c_p, Eterm arg1, Eterm arg2, Eterm arg3)
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(c_p, am_active);
}
-
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(c_p, am_active);
+ }
+
return res;
}
@@ -445,6 +463,9 @@ BIF_RETTYPE port_control_3(BIF_ALIST_3)
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(BIF_P, am_inactive);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(BIF_P, am_inactive);
+ }
p = id_or_name2port(BIF_P, BIF_ARG_1);
if (!p) {
@@ -456,6 +477,9 @@ BIF_RETTYPE port_control_3(BIF_ALIST_3)
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(BIF_P, am_active);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(BIF_P, am_active);
+ }
BIF_ERROR(BIF_P, BADARG);
}
@@ -495,6 +519,9 @@ BIF_RETTYPE port_control_3(BIF_ALIST_3)
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(BIF_P, am_active);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_profile_runnable_proc(BIF_P, am_active);
+ }
if (is_non_value(res)) {
BIF_ERROR(BIF_P, BADARG);
View
30 erts/emulator/beam/erl_process.c
@@ -4271,6 +4271,9 @@ suspend_process(ErtsRunQueue *rq, Process *p)
if ((erts_system_profile_flags.runnable_procs) && (p->rcount == 1) && (p->status != P_WAITING)) {
profile_runnable_proc(p, am_inactive);
}
+ if (DTRACE_ENABLED(percept_trace) && (p->rcount == 1) && (p->status != P_WAITING)) {
+ d_profile_runnable_proc(p, am_inactive);
+ }
p->status = P_SUSPENDED;
@@ -6190,6 +6193,11 @@ internal_add_to_runq(ErtsRunQueue *runq, Process *p)
|| prev_status == P_SUSPENDED)) {
profile_runnable_proc(p, am_active);
}
+ if ((DTRACE_ENABLED(percept_trace))
+ && (prev_status == P_WAITING
+ || prev_status == P_SUSPENDED)) {
+ d_profile_runnable_proc(p, am_active);
+ }
if (add_runq != runq)
erts_smp_runq_unlock(add_runq);
@@ -6231,6 +6239,9 @@ remove_proc_from_runq(ErtsRunQueue *rq, Process *p, int to_inactive)
if (res && erts_system_profile_flags.runnable_procs && to_inactive)
profile_runnable_proc(p, am_inactive);
+ if (res && DTRACE_ENABLED(percept_trace) && to_inactive) {
+ d_profile_runnable_proc(p, am_active);
+ }
#ifdef ERTS_SMP
ASSERT(!(p->status_flags & ERTS_PROC_SFLG_INRUNQ));
@@ -6627,6 +6638,10 @@ Process *schedule(Process *p, int calls)
&& (p->status == P_WAITING)) {
profile_runnable_proc(p, am_inactive);
}
+ if (DTRACE_ENABLED(percept_trace)
+ && (p->status == P_WAITING)) {
+ d_profile_runnable_proc(p, am_inactive);
+ }
if (IS_TRACED(p)) {
if (IS_TRACED_FL(p, F_TRACE_CALLS) && p->status != P_FREE) {
@@ -7606,6 +7621,9 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
if (IS_TRACED_FL(parent, F_TRACE_PROCS)) {
trace_proc(parent, parent, am_link, p->id);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc(parent, parent, am_link, p->id);
+ }
#ifdef DEBUG
ret = erts_add_link(&(parent->nlinks), LINK_PID, p->id);
@@ -7696,6 +7714,9 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
dtrace_fun_decode(p, mod, func, arity, process_name, mfa);
DTRACE2(process_spawn, process_name, mfa);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc_spawn(parent, p->id, mod, func, args);
+ }
#endif
error:
@@ -8612,6 +8633,9 @@ static void doit_exit_link(ErtsLink *lnk, void *vpcontext)
if (IS_TRACED_FL(rp, F_TRACE_PROCS)) {
trace_proc(p, rp, am_getting_unlinked, p->id);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc(p, rp, am_getting_unlinked, p->id);
+ }
}
}
ASSERT(rp != p);
@@ -8714,6 +8738,9 @@ erts_do_exit_process(Process* p, Eterm reason)
if (erts_system_profile_flags.runnable_procs && (p->status != P_WAITING)) {
profile_runnable_proc(p, am_inactive);
}
+ if (DTRACE_ENABLED(percept_trace) && (p->status != P_WAITING)) {
+ d_profile_runnable_proc(p, am_inactive);
+ }
#ifdef ERTS_SMP
erts_pix_lock(pix_lock);
@@ -8746,6 +8773,9 @@ erts_do_exit_process(Process* p, Eterm reason)
if (IS_TRACED_FL(p,F_TRACE_PROCS))
trace_proc(p, p, am_exit, reason);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc(p, p, am_exit, reason);
+ }
erts_trace_check_exiting(p->id);
View
140 erts/emulator/beam/erl_trace.c
@@ -2021,6 +2021,27 @@ trace_proc(Process *c_p, Process *t_p, Eterm what, Eterm data)
}
}
+void
+d_trace_proc(Process *c_p, Process *t_p, Eterm what, Eterm data)
+{
+ Eterm t;
+ Eterm* hp;
+ int need;
+
+#define LOCAL_HEAP_SIZE (5+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
+ hp = local_heap;
+ t = TUPLE4(hp, am_trace, t_p->id, what, data);
+ hp += 5;
+ hp = patch_ts(t, hp);
+
+ d_trace_save(t, t_p);
+
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
+}
/* Sends trace message:
* {trace_ts, ParentPid, spawn, ChildPid, {Mod, Func, Args}, Timestamp}
@@ -2092,6 +2113,78 @@ trace_proc_spawn(Process *p, Eterm pid,
}
}
+void
+d_trace_proc_spawn(Process *p, Eterm pid,
+ Eterm mod, Eterm func, Eterm args)
+{
+
+ Eterm mfa, t;
+ Eterm *hp;
+
+#define LOCAL_HEAP_SIZE (4+6+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
+ hp = local_heap;
+
+ mfa = TUPLE3(hp, mod, func, NIL);
+ hp += 4;
+
+ t = TUPLE5(hp, am_trace, p->id, am_spawn, pid, mfa);
+ hp += 6;
+
+ hp = patch_ts(t, hp);
+
+ d_trace_save(t, p);
+
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
+}
+
+void d_trace_save(Eterm t, Process *p)
+{
+
+ Eterm bt;
+ Uint sz, szb;
+ byte *bby = NULL, *bbt = NULL;
+ int i, j, c;
+ char* obtbuf;
+
+ bt = erts_term_to_binary(p, t, 0, TERM_TO_BINARY_DFLAGS);
+ szb = binary_size(bt);
+ sz = 5 + 4 * szb;
+
+ bby = erts_get_aligned_binary_bytes(bt, &bbt);
+
+ DTRACE_CHARBUF(btbuf, sz);
+ obtbuf = btbuf;
+
+ c = 0;
+ erts_sprintf(btbuf, "<<");
+ btbuf = btbuf + 2;
+ c = c + 2;
+
+ for (i = 0; i < szb; ++i) {
+
+ j = erts_sprintf(btbuf, "%d", (unsigned) bby[i]);
+ btbuf = btbuf + j;
+ c = c + j;
+
+ if (i < (szb - 1)) {
+ erts_sprintf(btbuf, ",");
+ btbuf = btbuf + 1;
+ c = c + 1;
+ }
+ }
+ erts_sprintf(btbuf, ">>.\0");
+
+ c = c + 5;
+
+ erts_free_aligned_binary_bytes(bbt);
+
+ DTRACE1(percept_trace, obtbuf);
+}
+
void save_calls(Process *p, Export *e)
{
struct saved_calls *scb = ERTS_PROC_GET_SAVED_CALLS_BUF(p);
@@ -3014,6 +3107,53 @@ profile_runnable_proc(Process *p, Eterm status){
}
/* End system_profile tracing */
+void
+d_profile_runnable_proc(Process *p, Eterm status){
+ Uint Ms, s, us;
+ Eterm *hp, t, timestamp;
+ Eterm where = am_undefined;
+
+#ifndef ERTS_SMP
+#define LOCAL_HEAP_SIZE (4 + 6 + 4)
+
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
+ hp = local_heap;
+#else
+ ErlHeapFragment *bp;
+ Uint hsz = 4 + 6 + 4;
+#endif
+
+ if (!p->current) {
+ p->current = find_function_from_pc(p->i);
+ }
+
+#ifdef ERTS_SMP
+ if (!p->current) {
+ hsz = 4 + 6;
+ }
+
+ bp = new_message_buffer(hsz);
+ hp = bp->mem;
+#endif
+
+ if (p->current) {
+ where = TUPLE3(hp, p->current[0], p->current[1], make_small(p->current[2]));
+ hp += 4;
+ } else {
+ where = make_small(0);
+ }
+
+ GET_NOW(&Ms, &s, &us);
+ timestamp = TUPLE3(hp, make_small(Ms), make_small(s), make_small(us));
+ hp += 4;
+ t = TUPLE5(hp, am_profile, p->id, status, where, timestamp);
+ hp += 6;
+
+ d_trace_save(t, p);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+}
#ifdef ERTS_SMP
View
8 erts/emulator/beam/erlang_dtrace.d
@@ -699,6 +699,14 @@ provider erlang {
*/
probe efile_drv__return(int, int, char *, int, int, int);
+ /**
+ * Trace something for percept.
+ *
+ * @param trace the trace.
+ *
+ */
+ probe percept__trace(char *);
+
/*
* NOTE:
* For formatting int64_t arguments within a D script, see:
View
3  erts/emulator/beam/global.h
@@ -1431,7 +1431,9 @@ void erts_trace_exception(Process* p, BeamInstr mfa[], Eterm class, Eterm value,
void erts_trace_return_to(Process *p, BeamInstr *pc);
void trace_sched(Process*, Eterm);
void trace_proc(Process*, Process*, Eterm, Eterm);
+void d_trace_proc(Process*, Process*, Eterm, Eterm);
void trace_proc_spawn(Process*, Eterm pid, Eterm mod, Eterm func, Eterm args);
+void d_trace_proc_spawn(Process*, Eterm pid, Eterm mod, Eterm func, Eterm args);
void save_calls(Process *p, Export *);
void trace_gc(Process *p, Eterm what);
/* port tracing */
@@ -1447,6 +1449,7 @@ Eterm erts_get_system_profile(void);
void profile_scheduler(Eterm scheduler_id, Eterm);
void profile_scheduler_q(Eterm scheduler_id, Eterm state, Eterm no_schedulers, Uint Ms, Uint s, Uint us);
void profile_runnable_proc(Process* p, Eterm status);
+void d_profile_runnable_proc(Process* p, Eterm status);
void profile_runnable_port(Port* p, Eterm status);
void erts_system_profile_setup_active_schedulers(void);
View
3  erts/emulator/beam/io.c
@@ -2104,6 +2104,9 @@ static void sweep_one_link(ErtsLink *lnk, void *vpsc)
trace_proc(NULL, rp, am_getting_unlinked,
psc->port);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc(NULL, rp, am_getting_unlinked, psc->port);
+ }
}
erts_destroy_link(rlnk);
}
View
6 erts/emulator/beam/register.c
@@ -229,6 +229,9 @@ int erts_register_name(Process *c_p, Eterm name, Eterm id)
if (IS_TRACED_FL(proc, F_TRACE_PROCS)) {
trace_proc(c_p, proc, am_register, name);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc(c_p, proc, am_register, name);
+ }
proc->reg = rp;
}
else if (port && rp->pt == port) {
@@ -555,6 +558,9 @@ int erts_unregister_name(Process *c_p,
if (IS_TRACED_FL(rp->p, F_TRACE_PROCS)) {
trace_proc(c_p, rp->p, am_unregister, r.name);
}
+ if (DTRACE_ENABLED(percept_trace)) {
+ d_trace_proc(c_p, rp->p, am_unregister, r.name);
+ }
#ifdef ERTS_SMP
if (rp->p != c_p) {
erts_smp_proc_unlock(rp->p, ERTS_PROC_LOCK_MAIN);
View
25 lib/percept/priv/dtrace/dtrace-percept.stap
@@ -0,0 +1,25 @@
+probe process("beam.smp").begin
+{
+ us = gettimeofday_us();
+ s = us / 1000000;
+ us = us % 1000000;
+ ms = s / 1000000;
+ s = s % 1000000;
+ printf("{profile_start, {%d,%d,%d}}.\n", ms, s, us);
+}
+
+probe process("beam.smp").mark("percept__trace")
+{
+ println(user_string($arg1));
+}
+
+probe process("beam.smp").end
+{
+ us = gettimeofday_us();
+ s = us / 1000000;
+ us = us % 1000000;
+ ms = s / 1000000;
+ s = s % 1000000;
+ printf("{profile_stop, {%d,%d,%d}}.\n", ms, s, us);
+}
+
View
40 lib/percept/src/percept.erl
@@ -35,6 +35,7 @@
stop_webserver/0,
stop_webserver/1,
analyze/1,
+ d_analyze/1,
% Application behaviour
start/2,
stop/1]).
@@ -134,6 +135,20 @@ analyze(Filename) ->
parse_and_insert(Filename,DB)
end.
+%% @spec d_analyze(string()) -> ok | {error, Reason}
+%% @doc Analyze DTrace file.
+
+-spec d_analyze(Filename :: file:filename()) ->
+ 'ok' | {'error', any()}.
+
+d_analyze(Filename) ->
+ case percept_db:start() of
+ {started, DB} ->
+ d_parse_and_insert(Filename,DB);
+ {restarted, DB} ->
+ d_parse_and_insert(Filename,DB)
+ end.
+
%% @spec start_webserver() -> {started, Hostname, Port} | {error, Reason}
%% Hostname = string()
%% Port = integer()
@@ -343,3 +358,28 @@ get_webserver_config(Servername, Port) when is_list(Servername), is_integer(Port
{bind_address, any},
{port, Port}],
{ok, Config}.
+
+%% d_parse_and_insert
+
+d_parse_and_insert(Filename, DB) ->
+ io:format("Parsing: ~p ~n", [Filename]),
+ T0 = erlang:now(),
+ case file:consult(Filename) of
+ {ok, Ts} -> d_send_loop(Ts, DB, T0, 0);
+ {error, Reason} -> {error, Reason}
+ end.
+
+d_send_loop([], DB, T0, Count) ->
+ DB ! {action, consolidate},
+ T1 = erlang:now(),
+ io:format("Parsed ~p entries in ~p s.~n", [Count, ?seconds(T1, T0)]),
+ io:format(" ~p created processes.~n", [length(percept_db:select({information, procs}))]),
+ io:format(" ~p opened ports.~n", [length(percept_db:select({information, ports}))]),
+ ok;
+d_send_loop([T|Ts], DB, T0, Count) ->
+ M = {insert, case is_binary(T) of
+ true -> binary_to_term(T);
+ false -> T
+ end},
+ DB ! M,
+ d_send_loop(Ts, DB, T0, Count+1).

No commit comments for this range

Something went wrong with that request. Please try again.