Paul Hinker's Weblog

pageicon Thursday Aug 31, 2006

More on making DTrace probes for Fortran

Last time I started looking at writing DTrace probes for Fortran routines. Since DTrace is a bit 'C centric' the calling sequence from Fortran is messy. Here's an example which uses the F95 Interface block to clean up the interface a little.

In the previous example, we were required to pass scalar parameters using the %val() convention since Fortran is a pass-by-reference language and the DTrace probe routines are expecting scalars to be passed by value. Using F95 interface blocks, we can clean this up.

% cat probeable.f

      program probeable
      implicit none

      integer i, inp

      inp = 1
      do while(.true.)
         call foo(inp)
         inp = inp + 1
         if (inp > 20) inp = 1
      end do
      end

      subroutine foo(inp)
      implicit none
      interface foobar
         subroutine __dtrace_foobar___foo(inp,val)
            integer,value :: inp
            integer,value :: val
         end subroutine
      end interface

      bind(C) __dtrace_foobar___foo

      integer inp, val1

      if (inp < 10) then
         call foobar(inp, 3)
         val1 = inp ** 3
      else
         val1 = inp ** 2
      endif
      return
      end
Note: Using the bind(C) attribute allows us to call a C routine from Fortran and get around the trailing '_' that Fortran wants to append to the called routine name. (details can be seen in the C-Fortran interface chapter Fortran Programming Guide) The interface block allows us to rename the routine from __dtrace_foobar___foo to something that doesn't require a couple dozen keystrokes. Finally, the VALUE attribute that is added to the 'inp' and 'val' parameters tells the compiler to pass those parameters by value.

For completeness, here's the whole sequence for building and using this probe:

% cat foobar.d

provider foobar {
   probe foo(int,int);
   probe bar();
};
% cat myprobeable.d
#!/usr/sbin/dtrace -s
:::foo
{
   @[probefunc,arg0,arg1] = count();
}
% f90 -c probeable.f
% dtrace -G -32 -s foobar.d probeable.o
% f90 -o probeable probeable.o foobar.o
% probeable &
% myprobeable
dtrace: script './myprobeable.d' matched 1 probe
[wait a couple seconds and the kill the 'probeable' process]
  foo_   7                3           190836
  foo_   5                3           190837
  foo_   4                3           190837
  foo_   2                3           190837
  foo_   3                3           190837
  foo_   9                3           190837
  foo_   1                3           190837
  foo_   6                3           190837
  foo_   8                3           190837
I've editted the output to prevent line wrapping. You can see that DTrace has intercepted 9 unique signatures during the time it was probing. The signatures are distinguished by the first two integers in columns 2 and 3. The last integer is the number of times that signature was detected.

As always, thanks for reading.

Thanks to Diane Meirowitz for suggesting the BIND(C) attribute instead of the less standard C$pragma(C).

Comments:

Post a Comment:
Comments are closed for this entry.