Search code examples
c++argumentstraceaspect

aspect c++ tracing function control flow and input output parameters


I am using aspectc++ to generate control flow of the program.

trace.ah:

    #ifndef __trace_ah__
    #define __trace_ah__

    #include <cstdio>
    // Control flow tracing example

    aspect trace {
            // print the function name before execution starts

            pointcut virtual methods() = "% ...::%(...)";

            advice execution (methods()) : before () {
                cout << "entering: " << JoinPoint::signature() << endl;
                // print input parameters**
            }

            advice execution(methods()) : after() {
                // print output parameters**            
                cout << "leaving: " << JoinPoint::signature() << endl;
            }
//prints return values of non void functions 
advice execution("% ...::%(...)" && !"void ...::%(...)") : after() 
{


    JoinPoint::Result res = *tjp->result();
    cout << "leaving " << tjp->signature()<< " << returning value--" << res<<endl;
}
};
    };

    #endif  

Question:

1.How to print the variables itself that are passed as arguments to the functions ?

2.How do I print the input parameters values of each function ?


Solution

  • #ifndef __trace_ah__
     #define __trace_ah__
    
    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    template <int I> struct ArgPrinter 
    {
      template <class JP> static inline void work (JP &tjp) {
        ArgPrinter<I - 1>::work (tjp);
        cout << "Arg " << I << ": " << *tjp.template arg<I - 1> () << endl;
      }
    };    
    
    template <> struct ArgPrinter<0> 
    {
      template <class JP> static inline void work (JP &tjp) {}
    };
    
    // Control flow tracing example
    
        aspect trace {
    
    
                pointcut virtual methods() = "% ...::%(...)";
    
        template <class JP> void print_args (JP &tjp) 
            {
                 ArgPrinter<JP::ARGS>::work (tjp);
            }
    
            advice execution (methods()) : before () 
        {
                    cout << "entering: " << JoinPoint::signature() << endl;
                tjp->arg(0);
            print_args (*tjp);
    
    
            }
    
        advice execution("% ...::%(...)" && !"void ...::%(...)") : after() 
        {   
                JoinPoint::Result res = *tjp->result();
                cout << "leaving " << tjp->signature()<< " << returning value--" << res<<endl;
        }
    
    
    };
      #endif