tc_report_match() is overridable.
authorJustin Seyster <jseyster@cs.sunysb.edu>
Thu, 17 Mar 2011 01:35:30 +0000 (21:35 -0400)
committerJustin Seyster <jseyster@cs.sunysb.edu>
Thu, 17 Mar 2011 01:35:30 +0000 (21:35 -0400)
Doxyfile
src/Makefile.am
src/tracecut-advice.c
src/tracecut-advice.h [new file with mode: 0644]

index a537fa5a6dbd01efb7d7579dd033186db776f56e..56333d85f4c8f11ea8f689be2489309b8ff0bd3d 100644 (file)
--- a/Doxyfile
+++ b/Doxyfile
@@ -585,7 +585,7 @@ INPUT_ENCODING         = UTF-8
 # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
 # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
 
-FILE_PATTERNS          = aop.h tracecut.h *.c
+FILE_PATTERNS          = aop.h tracecut.h tracecut-advice.h *.c
 
 # The RECURSIVE tag can be used to turn specify whether or not subdirectories
 # should be searched for input files as well. Possible values are YES and NO.
index 9326eab1060713389a747d9370c8799f20d6a0fe..f8a359ba209e85c494e919422628ff438af2484c 100644 (file)
@@ -11,4 +11,4 @@ libinteraspect_la_CPPFLAGS = -DHAVE_CONFIG_H -DIN_GCC -I$(gcc_includes)
 libtracecut_la_SOURCES = tracecut-advice.c nfa.c nfa.h
 libtracecut_la_CFLAGS = -Wall -Werror -fvisibility=hidden
 
-include_HEADERS = aop.h tracecut.h
+include_HEADERS = aop.h tracecut.h tracecut-advice.h
index 52bc438d5f402b3a25c43f7847935432f1b0dcdd..fe26a8b93240bbbd4eb3987811caf76db12982a3 100644 (file)
@@ -4,6 +4,7 @@
 #include <string.h>
 
 #include "nfa.h"
+#include "tracecut-advice.h"
 
 /* Advice functions should be externally visible. */
 #define ADVICE_FUNC __attribute__((visibility("default")))
@@ -26,23 +27,6 @@ struct tracecut {
 
 static struct tracecut *tracecut_array = NULL;
 
-struct param_val {
-  enum {
-    PV_VACANT = 0,
-    PV_POINTER,
-    PV_SIGNED_INT,
-    PV_UNSIGNED_INT,
-    PV_FP
-  } kind;
-
-  union {
-    uintptr_t ptr_value;
-    int64_t   int_val;
-    uint64_t  uint_val;
-    double    fp_val;
-  };
-};
-
 struct event {
   int symbol_index;
 
@@ -103,19 +87,33 @@ get_tracecut (int tc_index)
     }
 }
 
-void
-tc_report_match (struct tracecut *tc, struct tuple *tuple, int symbol_index)
+__attribute__((weak)) __attribute__((noinline)) void
+tc_report_match (const char *symbol, const struct matched_param *param_array,
+                int num_params)
 {
-  fprintf (stderr, "(Tracecut) Match triggered by symbol: %s.", tc->symbol_names[symbol_index]);
+  fprintf (stderr, "(Tracecut) Match triggered by symbol: %s.", symbol);
 
-  if (tc->num_params > 0)
+  if (num_params > 0)
     {
       int i;
 
       fprintf (stderr, "  Param values follow:\n");
-      for (i = 0; i < tc->num_params; i++)
-       fprintf (stderr, "  Param %s: 0x%p\n", tc->param_names[i],
-                (void *)tuple->param_vals[i].ptr_value);
+      for (i = 0; i < num_params; i++)
+       {
+         const char *name = param_array[i].name;
+         const struct param_val *value = param_array[i].value;
+
+         fprintf (stderr, "  Param %s: ", name);
+
+         switch (value->kind)
+           {
+           case PV_POINTER:
+             fprintf (stderr, " %p\n", (void *)value->ptr_value);
+             break;
+           default:
+             fprintf (stderr, " Bad value\n");
+           }
+       }
     }
   else
     {
@@ -124,6 +122,22 @@ tc_report_match (struct tracecut *tc, struct tuple *tuple, int symbol_index)
     }
 }
 
+static void
+report_match (struct tracecut *tc, struct tuple *tuple, int symbol_index)
+{
+  int i;
+  struct matched_param *param_array;
+
+  param_array = alloca (tc->num_params * sizeof (struct matched_param));
+  for (i = 0; i < tc->num_params; i++)
+    {
+      param_array[i].name = tc->param_names[i];
+      param_array[i].value = &tuple->param_vals[i];
+    }
+
+  tc_report_match (tc->symbol_names[symbol_index], param_array, tc->num_params);
+}
+
 static void
 insert_tuple (struct tracecut *tc, struct tuple *tuple)
 {
@@ -176,7 +190,7 @@ advance_state_machine (struct tracecut *tc, struct tuple *tuple, int symbol_inde
     {
       step (tuple->states[i], symbol_index);
       if (ismatch (tuple->states[i]))
-       tc_report_match (tc, tuple, symbol_index);
+       report_match (tc, tuple, symbol_index);
 
       if (isatstart (tuple->states[i]))
        num_trivial++;
@@ -214,21 +228,21 @@ event_matches_tuple (struct event *event, struct tuple *tuple)
          break;
        case PV_SIGNED_INT:
          if (tuple->param_vals[i].kind != PV_SIGNED_INT
-             || event->param_vals[i].int_val != tuple->param_vals[i].int_val)
+             || event->param_vals[i].int_value != tuple->param_vals[i].int_value)
            return 0;  /* Mismatch. */
          else
            ;  /* This param matches; keep looking. */
          break;
        case PV_UNSIGNED_INT:
          if (tuple->param_vals[i].kind != PV_UNSIGNED_INT
-             || event->param_vals[i].uint_val != tuple->param_vals[i].uint_val)
+             || event->param_vals[i].uint_value != tuple->param_vals[i].uint_value)
            return 0;  /* Mismatch. */
          else
            ;  /* This param matches; keep looking. */
          break;
        case PV_FP:
          if (tuple->param_vals[i].kind != PV_FP
-             || event->param_vals[i].fp_val != tuple->param_vals[i].fp_val)
+             || event->param_vals[i].fp_value != tuple->param_vals[i].fp_value)
            return 0;  /* Mismatch. */
          else
            ;  /* This param matches; keep looking. */
@@ -538,8 +552,8 @@ _tc_capture_signed_int_param (int tc_index, int symbol_index, int param_index,
       fatal_tracecut_error ("Out-of-bounds param value.");
     }
 
-  current_event->param_vals[param_index].kind    = PV_SIGNED_INT;
-  current_event->param_vals[param_index].int_val = param_val;
+  current_event->param_vals[param_index].kind = PV_SIGNED_INT;
+  current_event->param_vals[param_index].int_value = param_val;
 }
    
 ADVICE_FUNC void
@@ -561,8 +575,8 @@ _tc_capture_unsigned_int_param (int tc_index, int symbol_index, int param_index,
       fatal_tracecut_error ("Out-of-bounds param value.");
     }
 
-  current_event->param_vals[param_index].kind     = PV_UNSIGNED_INT;
-  current_event->param_vals[param_index].uint_val = param_val;
+  current_event->param_vals[param_index].kind = PV_UNSIGNED_INT;
+  current_event->param_vals[param_index].uint_value = param_val;
 }
 
 ADVICE_FUNC void
@@ -584,8 +598,8 @@ _tc_capture_float_param (int tc_index, int symbol_index, int param_index,
       fatal_tracecut_error ("Out-of-bounds param value.");
     }
 
-  current_event->param_vals[param_index].kind   = PV_FP;
-  current_event->param_vals[param_index].fp_val = param_val;
+  current_event->param_vals[param_index].kind = PV_FP;
+  current_event->param_vals[param_index].fp_value = param_val;
 }
 
 
diff --git a/src/tracecut-advice.h b/src/tracecut-advice.h
new file mode 100644 (file)
index 0000000..f5dd535
--- /dev/null
@@ -0,0 +1,100 @@
+#ifndef __AOP_TRACECUT_ADVICE_H__
+#define __AOP_TRACECUT_ADVICE_H__
+
+/* Copyright (c) 2011 Justin Seyster
+   Copyright (c) 2011 Erez Zadok
+   Copyright (c) 2011 Stony Brook University
+   Copyright (c) 2011 The Research Foundation of SUNY
+
+   This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation, either version 3 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License
+   and a copy of the GCC Runtime Library Exception along with this
+   program; see the files COPYING and COPYING.RUNTIME respectively.
+   If not, see <http://www.gnu.org/licenses/>. */
+
+/**
+ * \file tracecut-advice.h
+ * \brief Public interface for implementing tracut advice functions.
+ *
+ * When the tracecut monitoring engine matches a tracecut rule, it
+ * calls the tracecut match function, tc_report_match().  By default,
+ * tc_report_match() just prints information about the match to
+ * <code>stderr</code>, but it is possible to override
+ * tc_report_match() to perform some other action.
+ *
+ * Note that this include file is not intended for tracecut
+ * <i>plug-ins</i>.  Rather, it is intended for tracecut advice, which
+ * gets compiled and linked with the target program.
+ */
+
+/**
+ * \brief Value of a param.
+ *
+ * Stores the value of a param, along with what kind of param it is.
+ * There are four kinds of param, PV_POINTER, PV_SIGNED_INT,
+ * PV_UNSIGNED_INT, and PV_FP.  PV_VACANT is used internally; no param
+ * with kind PV_VACANT will ever be passed to tc_report_match().
+ *
+ * The param's value itself is stored in a transparent union.  You
+ * should only ever access the vaue using the union member that
+ * corresponds to the param's kind.  You can access a transparent
+ * union member as if it were a member of the struct.
+ */
+struct param_val {
+  enum {
+    PV_VACANT = 0,
+    PV_POINTER,
+    PV_SIGNED_INT,
+    PV_UNSIGNED_INT,
+    PV_FP
+  } kind;
+
+  union {
+    uintptr_t ptr_value;
+    int64_t int_value;
+    uint64_t uint_value;
+    double fp_value;
+  };
+};
+
+/**
+ * \brief The name and value of a param.
+ */
+struct matched_param
+{
+  const char *name;
+  const struct param_val *value;
+};
+
+/**
+ * This function gets called at runtime when a tracecut rule matches.
+ * Because it is marked as a weak symbol, if the target program (or
+ * some other library) implements tc_report_match(), it will override
+ * the default implementation.
+ *
+ * The default implementation prints the symbol that triggered the
+ * match and the value of each param to <code>stderr</code>.
+ *
+ * \param symbol The name of the symbol that triggered the match.
+ * \param param_array A list of params associated with the tracecut.
+ * Each entry in the array has the param's name, as well as its value.
+ * \param num_params The number of elements in the param_array list.
+ */
+extern void tc_report_match (const char *symbol,
+                            const struct matched_param *param_array,
+                            int num_params);
+
+#endif