Skip to content

Commit

Permalink
Update dtrace for changes in R15
Browse files Browse the repository at this point in the history
  • Loading branch information
psyeugenic authored and bufflig committed Mar 22, 2012
1 parent ad6387b commit 0fd4e39
Show file tree
Hide file tree
Showing 22 changed files with 216 additions and 188 deletions.
37 changes: 15 additions & 22 deletions README.dtrace.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,17 @@ Goals
Supported platforms
-------------------

The autoconf procedure is supported, I believe, for OS X/Snow Leopard
and OpenSolaris/64-bit. Just add the `--enable-dtrace` option your
command to run the `configure` script.

The code has been only very lightly tested on OS X. It ought to
compile on a Solaris 10 or OpenSolaris machine, but no promises yet.

The autoconf stuff is ugly right now. It could use some cleaning up.
For example:

* After editing the `erlang_dtrace.d` file, you need to re-run the
* top-level "configure" script in order to update `erlang_dtrace.h`.
* `make clean` will remove `erlang_dtrace.h`. A build will fail
unless the top-level "configure" script is re-run to re-create that
file.
* The `erlang_dtrace.h` file's location should probably be moved to an
OTP platform-specific build dir, for example,
`path/to/somewhere/i386-apple-darwin10.8.0`
* There are probably some other build by-products that are also being
put into the "wrong" directory, for example, `erlang_dtrace.o` for
Solaris platforms.
* OS X 10.6.x / Snow Leopard. It should also work for 10.7 / Lion,
but I haven't personally tested it.
* Solaris 10. I have done limited testing on Solaris 11 and
OpenIndiana release 151a, and both appear to work.
* FreeBSD 9.0, though please see the "FreeBSD 9.0 Release Notes"
section below!
* Linux via SystemTap compatibility. Please see the file
`README.systemtap.md` for more details.

Just add the `--enable-dtrace` option to your command when you run the
`configure` script.

Contributions
-------------
Expand All @@ -61,9 +51,12 @@ To build from scratch, use this recipe. If you're an experienced Git
user and wish to add my repository as a remote repository, be my
guest. Just resume the recipe at command #4.

NOTE: The `dtrace-experiment+michal2` branch is used for changes that
can be applied to both R14B and R15 releases.

% git clone git://github.com/slfritchie/otp.git
% cd otp
% git checkout -b dtrace-experiment origin/dtrace-experiment
% git checkout -b dtrace-experiment+michal2 origin/dtrace-experiment+michal2
% env ERL_TOP=`pwd` ./otp_build autoconf
% env ERL_TOP=`pwd` ./configure --enable-dtrace + whatever args you need
% env ERL_TOP=`pwd` make
Expand Down
6 changes: 5 additions & 1 deletion erts/emulator/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,11 @@ endif
endif

ifdef DTRACE_ENABLED
GENERATE += $(TARGET)/erlang_dtrace.h
# global.h causes problems by including dtrace-wrapper.h which includes
# the autogenerated erlang_dtrace.h ... so make erlang_dtrace.h very early.
generate: $(TARGET)/erlang_dtrace.h $(GENERATE)
else
generate: $(GENERATE)
endif

ifdef HIPE_ENABLED
Expand Down
85 changes: 15 additions & 70 deletions erts/emulator/beam/beam_emu.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@
#include "hipe_mode_switch.h"
#include "hipe_bif1.h"
#endif

#include <assert.h>
#include "dtrace-wrapper.h"

/* #define HARDDEBUG 1 */
Expand Down Expand Up @@ -1053,72 +1051,6 @@ init_emulator(void)
# define REG_tmp_arg2
#endif

ERTS_INLINE void
dtrace_proc_str(Process *process, char *process_buf)
{
dtrace_pid_str(process->id, process_buf);
}

ERTS_INLINE void
dtrace_pid_str(Eterm pid, char *process_buf)
{
snprintf(process_buf, DTRACE_TERM_BUF_SIZE, "<%lu.%lu.%lu>",
pid_channel_no(pid),
pid_number(pid),
pid_serial(pid));
}

ERTS_INLINE void
dtrace_port_str(Port *port, char *port_buf)
{
snprintf(port_buf, DTRACE_TERM_BUF_SIZE, "#Port<%lu.%lu>",
port_channel_no(port->id),
port_number(port->id));
}

ERTS_INLINE void
dtrace_drvport_str(ErlDrvPort drvport, char *port_buf)
{
Port *port = erts_drvport2port(drvport);

snprintf(port_buf, DTRACE_TERM_BUF_SIZE, "#Port<%lu.%lu>",
port_channel_no(port->id),
port_number(port->id));
}

ERTS_INLINE void
dtrace_fun_decode(Process *process,
Eterm module, Eterm function, int arity,
char *process_buf, char *mfa_buf)
{
char funbuf[DTRACE_TERM_BUF_SIZE];
char *funptr = funbuf;
char *p = NULL;

if (process_buf) {
dtrace_proc_str(process, process_buf);
}

erts_snprintf(funbuf, sizeof(funbuf), "%T", function);
/*
* I'm not quite sure how these function names are synthesized,
* but they almost always seem to be in the form of
* '-name/arity-fun-0-' so I'm chopping them up when it's -fun-0-
* (which seems to be the toplevel)
*/
if (funbuf[0] == '\'' && funbuf[1] == '-'
&& strlen(funbuf) > 3 && funbuf[strlen(funbuf) - 3] == '0') {
p = strchr(funbuf, '/');
if (p) {
*p = 0;
}
funptr += 2;
}

erts_snprintf(mfa_buf, DTRACE_TERM_BUF_SIZE, "%T:%s/%d",
module, funptr, arity);
}

#ifdef HAVE_DTRACE

#define DTRACE_CALL(p, m, f, a) \
Expand Down Expand Up @@ -1190,6 +1122,16 @@ dtrace_fun_decode(Process *process,

#endif /* HAVE_DTRACE */

void
dtrace_drvport_str(ErlDrvPort drvport, char *port_buf)
{
Port *port = erts_drvport2port(drvport);

erts_snprintf(port_buf, DTRACE_TERM_BUF_SIZE, "#Port<%lu.%lu>",
port_channel_no(port->id),
port_number(port->id));
}

/*
* process_main() is called twice:
* The first call performs some initialisation, including exporting
Expand Down Expand Up @@ -1376,7 +1318,8 @@ void process_main(void)
(Eterm)fptr[1], (Uint)fptr[2],
NULL, fun_buf);
} else {
snprintf(fun_buf, sizeof(fun_buf), "<unknown/%p>", next);
erts_snprintf(fun_buf, sizeof(fun_buf),
"<unknown/%p>", next);
}
}

Expand Down Expand Up @@ -1970,7 +1913,9 @@ void process_main(void)
if (DTRACE_ENABLED(message_receive)) {
Eterm token2 = NIL;
DTRACE_CHARBUF(receiver_name, DTRACE_TERM_BUF_SIZE);
Sint tok_label = 0, tok_lastcnt = 0, tok_serial = 0;
ERTS_DECLARE_DUMMY(Sint tok_label) = 0;
ERTS_DECLARE_DUMMY(Sint tok_lastcnt) = 0;
ERTS_DECLARE_DUMMY(Sint tok_serial) = 0;

dtrace_proc_str(c_p, receiver_name);
token2 = SEQ_TRACE_TOKEN(c_p);
Expand Down
16 changes: 11 additions & 5 deletions erts/emulator/beam/dist.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,8 +741,10 @@ erts_dsig_send_msg(ErtsDSigData *dsdp, Eterm remote, Eterm message)
Eterm token = NIL;
Process *sender = dsdp->proc;
int res;
Sint tok_label = 0, tok_lastcnt = 0, tok_serial = 0;
Uint msize = 0;
ERTS_DECLARE_DUMMY(Sint tok_label) = 0;
ERTS_DECLARE_DUMMY(Sint tok_lastcnt) = 0;
ERTS_DECLARE_DUMMY(Sint tok_serial) = 0;
ERTS_DECLARE_DUMMY(Uint msize) = 0;
DTRACE_CHARBUF(node_name, 64);
DTRACE_CHARBUF(sender_name, 64);
DTRACE_CHARBUF(receiver_name, 64);
Expand Down Expand Up @@ -788,8 +790,10 @@ erts_dsig_send_reg_msg(ErtsDSigData *dsdp, Eterm remote_name, Eterm message)
Eterm token = NIL;
Process *sender = dsdp->proc;
int res;
Sint tok_label = 0, tok_lastcnt = 0, tok_serial = 0;
Uint32 msize = 0;
ERTS_DECLARE_DUMMY(Sint tok_label) = 0;
ERTS_DECLARE_DUMMY(Sint tok_lastcnt) = 0;
ERTS_DECLARE_DUMMY(Sint tok_serial) = 0;
ERTS_DECLARE_DUMMY(Uint32 msize) = 0;
DTRACE_CHARBUF(node_name, 64);
DTRACE_CHARBUF(sender_name, 64);
DTRACE_CHARBUF(receiver_name, 128);
Expand Down Expand Up @@ -838,7 +842,9 @@ erts_dsig_send_exit_tt(ErtsDSigData *dsdp, Eterm local, Eterm remote,
DeclareTmpHeapNoproc(ctl_heap,6);
int res;
Process *sender = dsdp->proc;
Sint tok_label = 0, tok_lastcnt = 0, tok_serial = 0;
ERTS_DECLARE_DUMMY(Sint tok_label) = 0;
ERTS_DECLARE_DUMMY(Sint tok_lastcnt) = 0;
ERTS_DECLARE_DUMMY(Sint tok_serial) = 0;
DTRACE_CHARBUF(node_name, 64);
DTRACE_CHARBUF(sender_name, 64);
DTRACE_CHARBUF(remote_name, 128);
Expand Down
9 changes: 0 additions & 9 deletions erts/emulator/beam/dtrace-wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,6 @@

#define DTRACE_TERM_BUF_SIZE 256

#ifndef DTRACE_DRIVER_SKIP_FUNC_DECLARATIONS
inline void dtrace_proc_str(Process *process, char *process_buf);
inline void dtrace_pid_str(Eterm pid, char *process_buf);
inline void dtrace_port_str(Port *port, char *port_buf);
inline void dtrace_fun_decode(Process *process,
Eterm module, Eterm function, int arity,
char *process_buf, char *mfa_buf);
#endif

/*
* Some varieties of SystemTap macros do not like statically-sized
* char[N] buffers. (For example, CentOS 6's macros.)
Expand Down
10 changes: 6 additions & 4 deletions erts/emulator/beam/erl_async.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,7 @@ erts_get_async_ready_queue(Uint sched_id)

static ERTS_INLINE void async_add(ErtsAsync *a, ErtsAsyncQ* q)
{
/* DTRACE TODO: Get the queue length from erts_thr_q_enqueue() */
int len = -1;
int len;

if (is_internal_port(a->port)) {
#if ERTS_USE_ASYNC_READY_Q
Expand All @@ -275,6 +274,8 @@ static ERTS_INLINE void async_add(ErtsAsync *a, ErtsAsyncQ* q)
DTRACE_CHARBUF(port_str, 16);

erts_snprintf(port_str, sizeof(port_str), "%T", a->port);
/* DTRACE TODO: Get the queue length from erts_thr_q_enqueue() ? */
len = -1;
DTRACE2(aio_pool_add, port_str, len);
}
gcc_optimizer_hack++;
Expand All @@ -288,8 +289,7 @@ static ERTS_INLINE ErtsAsync *async_get(ErtsThrQ_t *q,
int saved_fin_deq = 0;
ErtsThrQFinDeQ_t fin_deq;
#endif
/* DTRACE TODO: Get the queue length from erts_thr_q_dequeue() somehow? */
int len = -1;
int len;

while (1) {
ErtsAsync *a = (ErtsAsync *) erts_thr_q_dequeue(q);
Expand All @@ -305,6 +305,8 @@ static ERTS_INLINE ErtsAsync *async_get(ErtsThrQ_t *q,
DTRACE_CHARBUF(port_str, 16);

erts_snprintf(port_str, sizeof(port_str), "%T", a->port);
/* DTRACE TODO: Get the length from erts_thr_q_dequeue() ? */
len = -1;
DTRACE2(aio_pool_get, port_str, len);
}
return a;
Expand Down
1 change: 0 additions & 1 deletion erts/emulator/beam/erl_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2055,7 +2055,6 @@ shrink_new_heap(Process *p, Uint new_sz, Eterm *objv, int nobj)
Uint heap_size = HEAP_TOP(p) - HEAP_START(p);
Sint offs;
Uint stack_size = p->hend - p->stop;
char pidbuf[DTRACE_TERM_BUF_SIZE];

ASSERT(new_sz < p->heap_sz);
sys_memmove(p->heap + new_sz - stack_size, p->stop, stack_size *
Expand Down
12 changes: 9 additions & 3 deletions erts/emulator/beam/erl_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,9 @@ erts_queue_dist_message(Process *rcvr,
Eterm token)
{
ErlMessage* mp;
Sint tok_label = 0, tok_lastcnt = 0, tok_serial = 0;
ERTS_DECLARE_DUMMY(Sint tok_label) = 0;
ERTS_DECLARE_DUMMY(Sint tok_lastcnt) = 0;
ERTS_DECLARE_DUMMY(Sint tok_serial) = 0;
#ifdef ERTS_SMP
ErtsProcLocks need_locks;
#endif
Expand Down Expand Up @@ -495,7 +497,9 @@ erts_queue_message(Process* receiver,

if (DTRACE_ENABLED(message_queued)) {
DTRACE_CHARBUF(receiver_name, DTRACE_TERM_BUF_SIZE);
Sint tok_label = 0, tok_lastcnt = 0, tok_serial = 0;
ERTS_DECLARE_DUMMY(Sint tok_label) = 0;
ERTS_DECLARE_DUMMY(Sint tok_lastcnt) = 0;
ERTS_DECLARE_DUMMY(Sint tok_serial) = 0;

dtrace_proc_str(receiver, receiver_name);
if (seq_trace_token != NIL && is_tuple(seq_trace_token)) {
Expand Down Expand Up @@ -822,7 +826,9 @@ erts_send_message(Process* sender,
Eterm token = NIL;
DTRACE_CHARBUF(sender_name, 64);
DTRACE_CHARBUF(receiver_name, 64);
Sint tok_label = 0, tok_lastcnt = 0, tok_serial = 0;
ERTS_DECLARE_DUMMY(Sint tok_label) = 0;
ERTS_DECLARE_DUMMY(Sint tok_lastcnt) = 0;
ERTS_DECLARE_DUMMY(Sint tok_serial) = 0;

BM_STOP_TIMER(system);
BM_MESSAGE(message,sender,receiver);
Expand Down
69 changes: 62 additions & 7 deletions erts/emulator/beam/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -1072,13 +1072,6 @@ void process_main(void);
Eterm build_stacktrace(Process* c_p, Eterm exc);
Eterm expand_error_value(Process* c_p, Uint freason, Eterm Value);
void erts_save_stacktrace(Process* p, struct StackTrace* s, int depth);
ERTS_INLINE void dtrace_proc_str(Process *process, char *process_buf);
ERTS_INLINE void dtrace_pid_str(Eterm pid, char *process_buf);
ERTS_INLINE void dtrace_port_str(Port *port, char *port_buf);
ERTS_INLINE void dtrace_drvport_str(ErlDrvPort port, char *port_buf);
ERTS_INLINE void dtrace_fun_decode(Process *process,
Eterm module, Eterm function, int arity,
char *process_buf, char *mfa_buf);

/* erl_init.c */

Expand Down Expand Up @@ -1981,4 +1974,66 @@ erts_alloc_message_heap(Uint size,
# define UseTmpHeapNoproc(Size) /* Nothing */
# define UnUseTmpHeapNoproc(Size) /* Nothing */
#endif /* HEAP_ON_C_STACK */

#if ERTS_GLB_INLINE_INCL_FUNC_DEF

#include "dtrace-wrapper.h"

ERTS_GLB_INLINE void
dtrace_pid_str(Eterm pid, char *process_buf)
{
erts_snprintf(process_buf, DTRACE_TERM_BUF_SIZE, "<%lu.%lu.%lu>",
pid_channel_no(pid),
pid_number(pid),
pid_serial(pid));
}

ERTS_GLB_INLINE void
dtrace_proc_str(Process *process, char *process_buf)
{
dtrace_pid_str(process->id, process_buf);
}

ERTS_GLB_INLINE void
dtrace_port_str(Port *port, char *port_buf)
{
erts_snprintf(port_buf, DTRACE_TERM_BUF_SIZE, "#Port<%lu.%lu>",
port_channel_no(port->id),
port_number(port->id));
}

ERTS_GLB_INLINE void
dtrace_fun_decode(Process *process,
Eterm module, Eterm function, int arity,
char *process_buf, char *mfa_buf)
{
char funbuf[DTRACE_TERM_BUF_SIZE];
char *funptr = funbuf;
char *p = NULL;

if (process_buf) {
dtrace_proc_str(process, process_buf);
}

erts_snprintf(funbuf, sizeof(funbuf), "%T", function);
/*
* I'm not quite sure how these function names are synthesized,
* but they almost always seem to be in the form of
* '-name/arity-fun-0-' so I'm chopping them up when it's -fun-0-
* (which seems to be the toplevel)
*/
if (funbuf[0] == '\'' && funbuf[1] == '-'
&& strlen(funbuf) > 3 && funbuf[strlen(funbuf) - 3] == '0') {
p = strchr(funbuf, '/');
if (p) {
*p = 0;
}
funptr += 2;
}

erts_snprintf(mfa_buf, DTRACE_TERM_BUF_SIZE, "%T:%s/%d",
module, funptr, arity);
}
#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */

#endif /* !__GLOBAL_H__ */
Loading

0 comments on commit 0fd4e39

Please sign in to comment.