         --- Writing a plugin module for eztrace ---

I - Introduction
================

This is an example of plugin module for eztrace.
This directory contains 2 sub-directories:


libexample_orig
---------------
This is an example library with functions that we want to trace using
eztrace. This library implements two simple functions
(example_function1 and example_function2).
This directory also includes a simple program that uses this library.

libexample_eztrace
------------------
This directory contains an example plugin for eztrace. This plugin
allows to trace the libexample functions with eztrace.


II - Files required for an eztrace module
=========================================

Writing an eztrace module requires 2 steps:
a. Recording events when a particular function is called. This step
happens during the application execution.
b. Interpreting the recorded events and generating a trace. This step
happens after the application execution, when eztrace_convert is run.

It is thus required to create two dynamic libraries that are loaded by
eztrace and eztrace_convert.


II.1 - Recording events
-----------------------
(see libexample_eztrace/example.c)

For recording events, eztrace relies on functions that redefines the
functions that have to be traced (MPI_Send, pthread_create, etc.)
Writing a plugin module for eztrace thus boils down to redefining all
the needed functions (for example example_function1 and
example_function2). Each redefined function f has to record an event
and to call the original f function. Usually such a function looks
like this:

int f(int arg1, double arg2)
{
  EZTRACE_EVENT2(F_START, arg1, arg2);
  int ret = f_orig(arg1, arg2);
  EZTRACE_EVENT1(F_STOP, ret);
  return ret;
}

This function records an event (which code is F_START), calls the
original f function, and records another after f (which code is F_STOP).
In order to call the original f function, the constructor of the
library should invoke the INTERCEPT macro:

  INTERCEPT("f", f_orig);

This macro replace the original f function with the one defined in the
current module. It copies the address of the original function in the
f_orig variable.


II.2 - Interpreting the recorded events
---------------------------------------
(see libexample_eztrace/eztrace_convert_example.c)

The interpretation plugin has to register to eztrace at startup. This can
be done by using a constructor (see the libinit function). During the registration,
the plugin defines a set of callbacks as well as general information on the plugin:

 int (*init)():
  The initialization function. This function is called once all the plugins are loaded
  and the trace is started. This function usually declared StateTypes, LinkTypes, etc.

 int (*handle)(eztrace_event_t* ev):
  The function that interprets events. It is called for each event in the Fxt trace.

 int (*handle_stats)(eztrace_event_t* ev):
  The function called for handling an event when eztrace_stats is called

 void (*print_stats)():
  Print the results of statistics.

 uint8_t module_prefix:
  Plugin identifier.

 char* name:
  Name of the plugin. It is used for selecting the list of plugins to use (ie. EZTRACE_TRACE)

 char* description:
  Description of the plugin (printed by eztrace_avail)
