6 Replies Latest reply: Dec 14, 2009 10:13 AM by 807559 RSS

    tracing user functions

    807559
      I am running a python test script which starts variouse programs. I want to trace the user specified function counts and time how long the application stays in each user function. As an example for hello world, I can use the following code. I would want to count how many times printit and printline are entered and how long the application spends in each. I do not need to follow the calls into the system or library calls (such as printf). I have found that I can use
      /cmdexec ==hello/
      but I have not seen how to get the calls to printit and printline. This is a trivial example, but I have applications with many functions and I do not want to have to instrument each one individually. I would also want to follow user calls further. For example if printit() called a routine called printone() I would want those counts.
      #include <stdio>
      int main(int argc, char **argv)
      {
          int i;
      
          for (i = 1; i < argv; i++)
          {
              printit(argv);
      }
      printline("");
      }

      void printit(char *arg)
      {
      printf("%s ", arg);
      }

      void printline(char *arg)
      {
      printf("%s\n", arg);
      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
        • 1. Re: tracing user functions
          807559
          The pid provider instruments the entry and return of every function in a C/C++ program. You can also address each executable's text generally by using a.out as the module name. So:

          pid$target:a.out::entry
          {
          @called[probefunc] = count();
          }

          will tell you how many times each function has been called during the trace.
          • 2. Re: tracing user functions
            807559
            This works when I call the script with the -c option and put in the explicit command. That is
            script.d -c "hello This is a test"
            However, when I am running a python set of tests that will trigger the hello application with various messages (as an example), the script will not find it. I suppose that I will have to modify the python script to call the dtrace script rather than the actual executable that it is testing. I was hoping to be able to avoid that.

            Thanks for the suggestion though.
            • 3. Re: tracing user functions
              807559
              You can get around that, sort of. DTrace has a progenyof() action that lets you determine if one process is the child of another. If you attach your Python script to a different DTrace script by -c, that script could be something like:

              #!/usr/sbin/dtrace -s

              #pragma D option quiet
              #pragma D option destructive

              proc:::exec-success
              / pid == progenyof($target) /
              {
              stop();
              system("script.d -p %d", pid);
              system("prun %d", pid);
              }

              Now you stop each child, run the instrumentation, then resume it. It does require the ability to run destructive actions. If you don't have root access, or it's been disabled system-wide, this approach doesn't help. If you don't want python to do that work, though -- and you don't mind DTrace doing pretty much the same thing -- it's a useful workaround.
              • 4. Re: tracing user functions
                807559
                Thanks, I will try it and see what happens
                • 5. Re: tracing user functions
                  807559
                  The information does not quite deal with the problem that I am having. Since the threads have not yet be started, the script will not start unless I put in a -Z. However, the output does not appear when I do that.
                  • 6. Re: tracing user functions
                    807559
                    Never mind. I made a mistake in the first line of the script. I need to put the -Z in the command line and not in the first line of the script.