/*
* %CopyrightBegin%
*
* Copyright Dustin Sallings, Michal Ptaszek, Scott Lystig Fritchie 2011-2012.
* All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* %CopyrightEnd%
*/
/*
* A note on probe naming: if "__" appears in a provider probe
* definition, then two things happen during compilation:
*
* 1. The "__" will turn into a hypen, "-", for the probe name.
* 2. The "__" will turn into a single underscore, "_", for the
* macro names and function definitions that the compiler and
* C developers will see.
*
* We'll try to use the following naming convention. We're a bit
* limited because, as a USDT probe, we can only specify the 4th part
* of the probe name, e.g. erlang*:::mumble. The 2nd part of the
* probe name is always going to be "beam" or "beam.smp", and the 3rd
* part of the probe name will always be the name of the function
* that's calling the probe.
*
* So, all probes will be have names defined in this file using the
* convention category__name or category__sub_category__name. This
* will translate to probe names of category-name or
* category-sub_category-name.
*
* Each of "category", "sub_category", and "name" may have underscores
* but may not have hyphens.
*/
provider erlang {
/**
* Fired when a message is sent from one local process to another.
*
* NOTE: The 'size' parameter is in machine-dependent words and
* that the actual size of any binary terms in the message
* are not included.
*
* @param sender the PID (string form) of the sender
* @param receiver the PID (string form) of the receiver
* @param size the size of the message being delivered (words)
* @param token_label for the sender's sequential trace token
* @param token_previous count for the sender's sequential trace token
* @param token_current count for the sender's sequential trace token
*/
probe message__send(char *sender, char *receiver, uint32_t size,
int token_label, int token_previous, int token_current);
/**
* Fired when a message is sent from a local process to a remote process.
*
* NOTE: The 'size' parameter is in machine-dependent words and
* that the actual size of any binary terms in the message
* are not included.
*
* @param sender the PID (string form) of the sender
* @param node_name the Erlang node name (string form) of the receiver
* @param receiver the PID/name (string form) of the receiver
* @param size the size of the message being delivered (words)
* @param token_label for the sender's sequential trace token
* @param token_previous count for the sender's sequential trace token
* @param token_current count for the sender's sequential trace token
*/
probe message__send__remote(char *sender, char *node_name, char *receiver,
uint32_t size,
int token_label, int token_previous, int token_current);
/**
* Fired when a message is queued to a local process. This probe
* will not fire if the sender's pid == receiver's pid.
*
* NOTE: The 'size' parameter is in machine-dependent words and
* that the actual size of any binary terms in the message
* are not included.
*
* NOTE: In cases of messages in external format (i.e. from another
* Erlang node), we probably don't know the message size
* without performing substantial extra computation. To
* avoid the extra CPU overhead, the message size may be
* reported as -1, which can appear to a D script as 4294967295.
*
* @param receiver the PID (string form) of the receiver
* @param size the size of the message being delivered (words)
* @param queue_len length of the queue of the receiving process
* @param token_label for the sender's sequential trace token
* @param token_previous count for the sender's sequential trace token
* @param token_current count for the sender's sequential trace token
*/
probe message__queued(char *receiver, uint32_t size, uint32_t queue_len,
int token_label, int token_previous, int token_current);
/**
* Fired when a message is 'receive'd by a local process and removed
* from its mailbox.
*
* NOTE: The 'size' parameter is in machine-dependent words and
* that the actual size of any binary terms in the message
* are not included.
*
* NOTE: In cases of messages in external format (i.e. from another
* Erlang node), we probably don't know the message size
* without performing substantial extra computation. To
* avoid the extra CPU overhead, the message size may be
* reported as -1, which can appear to a D script as 4294967295.
*
* @param receiver the PID (string form) of the receiver
* @param size the size of the message being delivered (words)
* @param queue_len length of the queue of the receiving process
* @param token_label for the sender's sequential trace token
* @param token_previous count for the sender's sequential trace token
* @param token_current count for the sender's sequential trace token
*/
probe message__receive(char *receiver, uint32_t size, uint32_t queue_len,
int token_label, int token_previous, int token_current);
/**
* Fired when an Eterm structure is being copied.
*
* NOTE: Due to the placement of this probe, the process ID of
* owner of the Eterm is not available.
*
* @param size the size of the structure
*/
probe copy__struct(uint32_t size);
/**
* Fired when an Eterm is being copied onto a process.
*
* @param proc the PID (string form) of the recipient process
* @param size the size of the structure
*/
probe copy__object(char *proc, uint32_t size);
/* PID, Module, Function, Arity */
/**
* Fired whenever a user function is being called locally.
*
* @param p the PID (string form) of the process
* @param mfa the m:f/a of the function
* @param depth the stack depth
*/
probe local__function__entry(char *p, char *mfa, int depth);
/**
* Fired whenever a user function is called externally
* (through an export entry).
*
* @param p the PID (string form) of the process
* @param mfa the m:f/a of the function
* @param depth the stack depth
*/
probe global__function__entry(char *p, char *mfa, int depth);
/**
* Fired whenever a user function returns.
*
* @param p the PID (string form) of the process
* @param mfa the m:f/a of the function
* @param depth the stack depth
*/
probe function__return(char *p, char *mfa, int depth);
/**
* Fired whenever a Built In Function is called.
*
* @param p the PID (string form) of the process
* @param mfa the m:f/a of the function
*/
probe bif__entry(char *p, char *mfa);
/**
* Fired whenever a Built In Function returns.
*
* @param p the PID (string form) of the process
* @param mfa the m:f/a of the function
*/
probe bif__return(char *p, char *mfa);
/**
* Fired whenever a Native Function is called.
*
* @param p the PID (string form) of the process
* @param mfa the m:f/a of the function
*/
probe nif__entry(char *p, char *mfa);
/**
* Fired whenever a Native Function returns.
*
* @param p the PID (string form) of the process
* @param mfa the m:f/a of the function
*/
probe nif__return(char *p, char *mfa);
/**
* Fired when a major GC is starting.
*
* @param p the PID (string form) of the exiting process
* @param need the number of words needed on the heap
*/
probe gc_major__start(char *p, int need);
/**
* Fired when a minor GC is starting.
*
* @param p the PID (string form) of the exiting process
* @param need the number of words needed on the heap
*/
probe gc_minor__start(char *p, int need);
/**
* Fired when a major GC is starting.
*
* @param p the PID (string form) of the exiting process
* @param reclaimed the amount of space reclaimed
*/
probe gc_major__end(char *p, int reclaimed);
/**
* Fired when a minor GC is starting.
*
* @param p the PID (string form) of the exiting process
* @param reclaimed the amount of space reclaimed
*/
probe gc_minor__end(char *p, int reclaimed);
/**
* Fired when a process is spawned.
*
* @param p the PID (string form) of the new process.
* @param mfa the m:f/a of the function
*/
probe process__spawn(char *p, char *mfa);
/**
* Fired when a process is exiting.
*
* @param p the PID (string form) of the exiting process
* @param reason the reason for the exit (may be truncated)
*/
probe process__exit(char *p, char *reason);
/**
* Fired when exit signal is delivered to a local process.
*
* @param sender the PID (string form) of the exiting process
* @param receiver the PID (string form) of the process receiving EXIT signal
* @param reason the reason for the exit (may be truncated)
*/
probe process__exit_signal(char *sender, char *receiver, char *reason);
/**
* Fired when exit signal is delivered to a remote process.
*
* @param sender the PID (string form) of the exiting process
* @param node_name the Erlang node name (string form) of the receiver
* @param receiver the PID (string form) of the process receiving EXIT signal
* @param reason the reason for the exit (may be truncated)
* @param token_label for the sender's sequential trace token
* @param token_previous count for the sender's sequential trace token
* @param token_current count for the sender's sequential trace token
*/
probe process__exit_signal__remote(char *sender, char *node_name,
char *receiver, char *reason,
int token_label, int token_previous, int token_current);
/**
* Fired when a process is scheduled.
*
* @param p the PID (string form) of the newly scheduled process
* @param mfa the m:f/a of the function it should run next
*/
probe process__scheduled(char *p, char *mfa);
/**
* Fired when a process is unscheduled.
*
* @param p the PID (string form) of the process that has been
* unscheduled.
*/
probe process__unscheduled(char *p);
/**
* Fired when a process goes into hibernation.
*
* @param p the PID (string form) of the process entering hibernation
* @param mfa the m:f/a of the location to resume
*/
probe process__hibernate(char *p, char *mfa);
/**
* Fired when a process is unblocked after a port has been unblocked.
*
* @param p the PID (string form) of the process that has been
* unscheduled.
* @param port the port that is no longer busy (i.e., is now unblocked)
*/
probe process__port_unblocked(char *p, char *port);
/**
* Fired when process' heap is growing.
*
* @param p the PID (string form)
* @param old_size the size of the old heap
* @param new_size the size of the new heap
*/
probe process__heap_grow(char *p, int old_size, int new_size);
/**
* Fired when process' heap is shrinking.
*
* @param p the PID (string form)
* @param old_size the size of the old heap
* @param new_size the size of the new heap
*/
probe process__heap_shrink(char *p, int old_size, int new_size);
/* network distribution */
/**
* Fired when network distribution event monitor events are triggered.
*
* @param node the name of the reporting node
* @param what the type of event, e.g., nodeup, nodedown
* @param monitored_node the name of the monitored node
* @param type the type of node, e.g., visible, hidden
* @param reason the reason term, e.g., normal, connection_closed, term()
*/
probe dist__monitor(char *node, char *what, char *monitored_node,
char *type, char *reason);
/**
* Fired when network distribution port is busy (i.e. blocked),
* usually due to the remote node not consuming distribution
* data quickly enough.
*
* @param node the name of the reporting node
* @param port the port ID of the busy port
* @param remote_node the name of the remote node.
* @param pid the PID (string form) of the local process that has
* become unschedulable until the port becomes unblocked.
*/
probe dist__port_busy(char *node, char *port, char *remote_node,
char *pid);
/**
* Fired when network distribution's driver's "output" callback is called
*
* @param node the name of the reporting node
* @param port the port ID of the busy port
* @param remote_node the name of the remote node.
* @param bytes the number of bytes written
*/
probe dist__output(char *node, char *port, char *remote_node, int bytes);
/**
* Fired when network distribution's driver's "outputv" callback is called
*
* @param node the name of the reporting node
* @param port the port ID of the busy port
* @param remote_node the name of the remote node.
* @param bytes the number of bytes written
*/
probe dist__outputv(char *node, char *port, char *remote_node, int bytes);
/**
* Fired when network distribution port is no longer busy (i.e. blocked).
*
* NOTE: This probe may fire multiple times after the same single
* dist-port_busy probe firing.
*
* @param node the name of the reporting node
* @param port the port ID of the busy port
* @param remote_node the name of the remote node.
*/
probe dist__port_not_busy(char *node, char *port, char *remote_node);
/* ports */
/**
* Fired when new port is opened.
*
* @param process the PID (string form)
* @param port_name the string used when the port was opened
* @param port the Port (string form) of the new port
*/
probe port__open(char *process, char *port_name, char *port);
/**
* Fired when port_command is issued.
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
* @param command_type type of the issued command, one of: "close", "command" or "connect"
*/
probe port__command(char *process, char *port, char *port_name, char *command_type);
/**
* Fired when port_control is issued.
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
* @param command_no command number that has been issued to the port
*/
probe port__control(char *process, char *port, char *port_name, int command_no);
/**
* Fired when port is closed via port_close/1 (reason = 'normal')
* or is sent an exit signal.
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
* @param reason Erlang term representing the exit signal, e.g. 'normal'
*/
probe port__exit(char *process, char *port, char *port_name,
char *new_process);
/**
* Fired when port_connect is issued.
*
* @param process the PID (string form) of the current port owner
* @param port the Port (string form)
* @param port_name the string used when the port was opened
* @param new_process the PID (string form) of the new port owner
*/
probe port__connect(char *process, char *port, char *port_name,
char *new_process);
/**
* Fired when a port is busy (i.e. blocked)
*
* @param port the port ID of the busy port
*/
probe port__busy(char *port);
/**
* Fired when a port is no longer busy (i.e. no longer blocked)
*
* @param port the port ID of the not busy port
*/
probe port__not_busy(char *port);
/* drivers */
/**
* Fired when drivers's "init" callback is called.
*
* @param name the name of the driver
* @param major the major version number
* @param minor the minor version number
* @param flags the flags argument
*/
probe driver__init(char *name, int major, int minor, int flags);
/**
* Fired when drivers's "start" callback is called.
*
* @param process the PID (string form) of the calling process
* @param name the name of the driver
* @param port the Port (string form) of the driver's port
*/
probe driver__start(char *process, char *name, char *port);
/**
* Fired when drivers's "stop" callback is called.
*
* @param process the PID (string form) of the calling process
* @param name the name of the driver
* @param port the Port (string form) of the driver's port
*/
probe driver__stop(char *process, char *name, char *port);
/**
* Fired when drivers's "finish" callback is called.
*
* @param name the name of the driver
*/
probe driver__finish(char *name);
/**
* Fired when drivers's "flush" callback is called.
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
*/
probe driver__flush(char *process, char *port, char *port_name);
/**
* Fired when driver's "output" callback is called
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
* @param bytes the number of bytes written
*/
probe driver__output(char *node, char *port, char *port_name, int bytes);
/**
* Fired when driver's "outputv" callback is called
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
* @param bytes the number of bytes written
*/
probe driver__outputv(char *node, char *port, char *port_name, int bytes);
/**
* Fired when driver's "control" callback is called
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
* @param command the command #
* @param bytes the number of bytes written
*/
probe driver__control(char *node, char *port, char *port_name,
int command, int bytes);
/**
* Fired when driver's "call" callback is called
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
* @param command the command #
* @param bytes the number of bytes written
*/
probe driver__call(char *node, char *port, char *port_name,
int command, int bytes);
/**
* Fired when driver's "event" callback is called
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
*/
probe driver__event(char *node, char *port, char *port_name);
/**
* Fired when driver's "ready_input" callback is called
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
*/
probe driver__ready_input(char *node, char *port, char *port_name);
/**
* Fired when driver's "read_output" callback is called
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
*/
probe driver__ready_output(char *node, char *port, char *port_name);
/**
* Fired when driver's "timeout" callback is called
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
*/
probe driver__timeout(char *node, char *port, char *port_name);
/**
* Fired when drivers's "ready_async" callback is called.
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
*/
probe driver__ready_async(char *process, char *port, char *port_name);
/**
* Fired when driver's "process_exit" callback is called
*
* @param process the PID (string form)
* @param port the Port (string form)
* @param port_name the string used when the port was opened
*/
probe driver__process_exit(char *node, char *port, char *port_name);
/**
* Fired when driver's "stop_select" callback is called
*
* @param name the name of the driver
*/
probe driver__stop_select(char *name);
/* Async driver pool */
/**
* Show the post-add length of the async driver thread pool member's queue.
*
* NOTE: The port name is not available: additional lock(s) must
* be acquired in order to get the port name safely in an SMP
* environment. The same is true for the aio__pool_get probe.
*
* @param port the Port (string form)
* @param new queue length
*/
probe aio_pool__add(char *, int);
/**
* Show the post-get length of the async driver thread pool member's queue.
*
* @param port the Port (string form)
* @param new queue length
*/
probe aio_pool__get(char *, int);
/* Probes for efile_drv.c */
/**
* Entry into the efile_drv.c file I/O driver
*
* For a list of command numbers used by this driver, see the section
* "Guide to efile_drv.c probe arguments" in ../../../HOWTO/DTRACE.md.
* That section also contains explanation of the various integer and
* string arguments that may be present when any particular probe fires.
*
* NOTE: Not all Linux platforms (using SystemTap) can support
* arguments beyond arg9.
*
*
* TODO: Adding the port string, args[10], is a pain. Making that
* port string available to all the other efile_drv.c probes
* will be more pain. Is the pain worth it? If yes, then
* add them everywhere else and grit our teeth. If no, then
* rip it out.
*
* @param thread-id number of the scheduler Pthread arg0
* @param tag number: {thread-id, tag} uniquely names a driver operation
* @param user-tag string arg2
* @param command number arg3
* @param string argument 1 arg4
* @param string argument 2 arg5
* @param integer argument 1 arg6
* @param integer argument 2 arg7
* @param integer argument 3 arg8
* @param integer argument 4 arg9
* @param port the port ID of the busy port args[10]
*/
probe efile_drv__entry(int, int, char *, int, char *, char *,
int64_t, int64_t, int64_t, int64_t, char *);
/**
* Entry into the driver's internal work function. Computation here
* is performed by a async worker pool Pthread.
*
* @param thread-id number
* @param tag number
* @param command number
*/
probe efile_drv__int_entry(int, int, int);
/**
* Return from the driver's internal work function.
*
* @param thread-id number
* @param tag number
* @param command number
*/
probe efile_drv__int_return(int, int, int);
/**
* Return from the efile_drv.c file I/O driver
*
* @param thread-id number arg0
* @param tag number arg1
* @param user-tag string arg2
* @param command number arg3
* @param Success? 1 is success, 0 is failure arg4
* @param If failure, the errno of the error. arg5
*/
probe efile_drv__return(int, int, char *, int, int, int);
/*
* NOTE:
* For formatting int64_t arguments within a D script, see:
*
* http://mail.opensolaris.org/pipermail/dtrace-discuss/2006-November/002830.html
* Summary:
* "1) you don't need the 'l' printf() modifiers with DTrace ever"
*/
/*
* NOTE: For file_drv_return + SMP + R14B03 (and perhaps other
* releases), the sched-thread-id will be the same as the
* work-thread-id: erl_async.c's async_main() function
* will call the asynchronous invoke function and then
* immediately call the drivers ready_async function while
* inside the same I/O worker pool thread.
* For R14B03's source, see erl_async.c lines 302-317.
*/
};
#pragma D attributes Evolving/Evolving/Common provider erlang provider
#pragma D attributes Private/Private/Common provider erlang module
#pragma D attributes Private/Private/Common provider erlang function
#pragma D attributes Evolving/Evolving/Common provider erlang name
#pragma D attributes Evolving/Evolving/Common provider erlang args