[Prev][Next][Index]

SgFunctionSymb::numberOfParameters returns bogus value




Hi. 

We're having a problem here which we are unable to understand. The
problem could be in our code or it could be in Sage, it's hard to say at
this point. The symptom is that after a certain instrumentation has been
performed on a procedure (a declaration declaring a variable of class
type with parameters to the constructor has been inserted at the head of
the procedure), SgFunctionSymb::numberOfParameters returns the wrong
number of parameters for the function within which the variable was
declared -- the number is 1 too high. 

This error occurs for every instrumented function in the depfile.

Sequence of events: pc++ is run to create trc-temp.C, instrumented for
tracing. The depfile is saved to disk, whence TAU reads it and analyzes
it. The error is discovered during call graph construction.

Running dumpdep is unhelpful; the output looks fine with a parameter
list of the correct length.

If the number of parameters were stored somewhere and got out of sync or
were overwritten due to a pointer error this would explain the error,
but numberOfParameters recomputes it every time.

If a pointer error (in Sage?) 'lengthened' the parameter
list then the error would be explained, but then either

- the depfile should have contained the error (but it doesn't); or
- the error must show up after the depfile has been read for analysis
  (but this seems unlikely since only instrumented functions exhibit the
  error).

Our only explanation right now is really that there is some wrong
information in the depfile which messes up numberOfParameters (or the
call graph module, for that matter) but which is not displayed by
dumpdep, and that this wrong information is due either to a bug in Sage
or a bug in the instrumenter.

The structure of the rest of the message is an example of the code
before and after instrumentation, and then an exposition of the
instrumentation code. What we want to discover is:
 - who's got the error (instrumentation code or sage)
 - how to fix it

The following code is the code before instrumentation:

	#include "pcxx.h"
	#include "pcxx_events.h"  // Include event tracing definitions

	void foo() { }

	void Processor_Main()
	{
	  // Several statements to enable tracing (size limit).
	  foo();
	  foo();
	  foo();
	  foo();
	}

After instrumentation there is a lot of gunk here, of course, but
Processor_Main has been instrumented in the following way (output from
pc++):

	void   Processor_Main(){
	      Profiler pcxx_P(0, 0, 653);
	      foo();
	      foo();
	      foo();
	      foo();
	}

As you can see, Processor_Main still takes 0 arguments, and when
sgCallGraph steps through the parameter list of the procedure, it also
finds 0. But numberOfParameters() returns 1.

The likely culprit is of course the instrumentation code. Here is the
relevant code from instr/instr.C, in function instrFunctions:

        /* -- declare variable pcxx_P of type class Profiler       -- */
        /* ---------------------------------------------------------- */
        SgSymbol *pcxx_P = new SgVariableSymb("pcxx_P", *t);
        pcxx_P->declareTheSymbol(*func);

        /* -- build 1. argument for constructor (eventID)          -- */
        /* ---------------------------------------------------------- */
        SgVariableSymb IDsymb("Ident");
        numfunc = newEventId (classname, funcname, funcsymb->id());
        e1 = new SgValueExp(numfunc);

        if ( ! profileMode )
        {
          /* -- build 2. Argument for MemberOfElement functions    -- */
          /* -- normal functions get argument "0".                 -- */
          /* -------------------------------------------------------- */
          if ( isMoE )
            e2 = new SgVarRefExp(IDsymb);
          else
            e2 = new SgValueExp(0);

          /* -- build 3. Argument: id of function symbol           -- */
          /* -------------------------------------------------------- */
          e3 = new SgValueExp(funcsymb->id());

          e = new SgExprListExp(*e3);
          args = &SgExprListOp(*e2, *e);
          args = &SgExprListOp(*e1, *args);
        }
        else if ( res == COUNT_ONLY ) {
	  // not relevant for the discussion
        }
        else
          // not relevant for the discussion

        /* -- finish building "pcxx_P" constructor arguments and   -- */
        /* -- add them                                             -- */
        /* ---------------------------------------------------------- */
        SgExpression *classinit = new SgExpression(CLASSINIT_OP); 
        classinit->setRhs(*args); 
        SgExpression *pcxx_P_ref = new SgVarRefExp(*pcxx_P);
        classinit->setLhs(*pcxx_P_ref);
        SgStatement *st = func->lexNext();
        SgExpression *list = st->expr(0);
        list->setLhs(*classinit);

Is this code valid? Are there better ways to accomplish what we want to
accomplish? Are there any known bugs?

--lars