Adds and documents tc_set_main_function().
authorJustin Seyster <jseyster@cs.sunysb.edu>
Thu, 17 Mar 2011 02:03:51 +0000 (22:03 -0400)
committerJustin Seyster <jseyster@cs.sunysb.edu>
Thu, 17 Mar 2011 02:03:51 +0000 (22:03 -0400)
src/tracecut.c
src/tracecut.h

index 4015e30cb43a0aa84c6d55672347b65b13467053..c7d6d0e2b1f943ed743ee3ec4f75cdc5cb68861d 100644 (file)
@@ -114,6 +114,10 @@ static struct tc_tracecut *tracecut_list = NULL;
    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
@@ -201,8 +205,8 @@ tc_reset_error (struct tc_tracecut *tc)
       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) ||
@@ -246,7 +250,7 @@ tc_add_param (struct tc_tracecut *tc, const char *name,
   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;
 
@@ -742,10 +746,16 @@ insert_transition_event_advice (struct aop_joinpoint *jp, int tc_index,
                     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)
@@ -837,6 +847,19 @@ get_num_rules (struct tc_tracecut *tc)
   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)
 {
@@ -899,6 +922,24 @@ 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)
 {
@@ -909,9 +950,38 @@ 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)
 {
index c04e33fa4447799a53f7f04d2b3e06dc58e1f324..f219c1350370eca52b33f423eb71478dc42300be 100644 (file)
@@ -111,6 +111,7 @@ extern void tc_free_tracecut (struct tc_tracecut *tc);
 
 extern void tc_insert_tracecut_init_advice (struct aop_joinpoint *jp);
 
+extern void tc_set_main_function (const char *func_name);
 extern void tc_register_tracecut_pass (void);
 
 #endif