illegal to modify any existing tracecut objects. */
static int tc_in_compilation = 0;
+/* The name of the function where the tracecut plug-in will insert its
+ initialization. */
+static const char *main_func = NULL;
+
/* Go through the master list of tracecuts and give each a consecutive
index. */
static void
tc->tc_error = TC_SUCCESS;
}
-enum tc_error
-tc_check_param_type(const struct aop_type *type)
+static enum tc_error
+check_param_type(const struct aop_type *type)
{
if(aop_is_pointer_type (type) ||
aop_is_all_signed_subtype (type) ||
if (tc_in_compilation)
return return_error (tc, TC_BAD_CONTEXT);
- tc_err = tc_check_param_type(type);
+ tc_err = check_param_type(type);
if(tc_err != TC_SUCCESS)
return tc_err;
AOP_TERM_ARG);
}
+/**
+ * \cond HIDDEN_SYMBOLS
+ */
struct join_on_call_arg {
struct tc_tracecut *tc;
struct tc_call_symbol *symbol;
};
+/**
+ * \endcond
+ */
static void
join_on_call (struct aop_joinpoint *jp, void *callback_arg)
return num_rules;
}
+/**
+ * Adds advice calls that initialize the tracecut runtime. You will
+ * always almost want to use tc_set_main_function(), which
+ * automatically adds the tracecut initialization advice, instead of
+ * this function.
+ *
+ * If you do want to manually add tracecut initialization, you must
+ * create your own InterAspect pass that finds a join point where
+ * initialization should go. This join point should execute only
+ * once, right when you want tracecut monitoring to start.
+ *
+ * \param jp The join point to insert initialization at.
+ */
void
tc_insert_tracecut_init_advice (struct aop_joinpoint *jp)
{
}
}
+static void
+join_on_main (struct aop_joinpoint *jp, void *data)
+{
+ tc_insert_tracecut_init_advice(jp);
+}
+
+static void
+add_init_instrumentation ()
+{
+ struct aop_pointcut *pc;
+
+ aop_assert (main_func != NULL);
+
+ pc = aop_match_function_entry ();
+ aop_filter_entry_by_name (pc, main_func);
+ aop_join_on (pc, join_on_main, NULL);
+}
+
static unsigned int
tracecut_pass (void)
{
for (tc = tracecut_list; tc != NULL; tc = tc->next)
add_instrumentation_for_tracecut (tc);
+ if (main_func != NULL)
+ add_init_instrumentation ();
+
return 0;
}
+/**
+ * Specifies the name of the target program's <i>main</i> function.
+ * The main function should be a function that executes exactly once
+ * at the beginning of program execution. Usually, <code>main</code>
+ * is the obvious main function.
+ *
+ * The tracecut plug-in will insert tracecut runtime initialization
+ * code at the entry to the main function. For tracecut monitoring to
+ * work, you must either set a main function or manually add this
+ * initiliazation code using tc_insert_tracecut_init_advice().
+ *
+ * \param func_name The name of the main function.
+ */
+void
+tc_set_main_function (const char *func_name)
+{
+ free ((char *)main_func);
+ main_func = strdup (func_name);
+ aop_assert (func_name != NULL); /* This is virtually impossible! */
+}
+
+/**
+ * Call this from your aop_main() function to register a pass that
+ * will add tracecut instrumentation. A tracecut plug-in will not do
+ * anything without this call!
+ */
void
tc_register_tracecut_pass (void)
{