Search code examples
functionargumentstracesystemtap

systemtap userspace function tracing


I have a simple c++ program

main.cpp

#include <iostream>
using namespace std;

int addition (int a, int b)
{
  int r;
  r=a+b;
  return r;
}

int main ()
{
  int z;
  z = addition (5,3);
  cout << "The result is " << z;
}

I want to generate the function tracing for this - print function names and its input output and return types

My systemtap script : para-callgraph.stp

#! /usr/bin/env stap

function trace(entry_p, extra) {
  %( $# > 1 %? if (tid() in trace) %)
  printf("%s%s%s %s\n",
         thread_indent (entry_p),
         (entry_p>0?"->":"<-"),
         probefunc (),
         extra)
}


probe $1.call   { trace(1, $$parms)  }
probe $1.return { trace(-1, $$return) }

My C++ Exec is called : a ( compiled as g++ -g main.cpp)

Command I run 
stap para-callgraph.stp 'process("a").function("*")' -c "./a > /dev/null"

 0 a(15119):->_GLOBAL__I__Z8additionii 
    27 a(15119): ->__static_initialization_and_destruction_0 __initialize_p=0x0 __priority=0x0
   168 a(15119): <-__static_initialization_and_destruction_0 
   174 a(15119):<-_GLOBAL__I__Z8additionii 
     0 a(15119):->main 
    18 a(15119): ->addition a=0x0 b=0x400895
    30 a(15119): <-addition return=0x8
   106 a(15119):<-main return=0x0

Here ->addition a=0x0 b=0x400895 : its address and not actual values ie 5, 3 which I want.

How to modify my stap script?

Solution

  • This appears to be a systemtap bug. It should print the value of b, not its address. Please report it to the [email protected] mailing list (with compiler/etc. versions and other info, as outlined in man error::reporting.

    As to changing the script, the $$parms part is where the local variables are being transformed into a pretty-printed string. It could be changed to something like...

    trace(1, $$parms . (@defined($foobar) ? (" foobar=".$foobar$) : ""))
    

    to append foobar=XYZ to the trace record, whereever a parameter foobar is available. To work around the systemtap bug in question, you could try

    trace(1, $$parms . (@defined($b) ? (" *b=".user_int($b)) : ""))
    

    to dereference the b variable as if it were an int *.