public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* static user probes
@ 2008-10-02 21:33 Stan Cox
  2008-10-02 21:43 ` Roland McGrath
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Stan Cox @ 2008-10-02 21:33 UTC (permalink / raw)
  To: systemtap

Here is an example of dtrace static defined tracing probes and a stap 
mockup doing something similar using uprobes.

Makefile:
CC=/usr/sfw/bin/gcc
DTRACE=/usr/sbin/dtrace
hello: helloprobes.o hello.o
         $(CC) -o hello helloprobes.o hello.o
helloprobes.o: hello.o
         $(DTRACE) -G -s helloprobes.d hello.o
         dis hello.o > hello.2.dis
hello.o:
         $(CC) -c hello.c
         dis hello.o > hello.1.dis

helloprobes.d:
provider hello {
    probe printDemo(char*);
};

hellotest_.d:
BEGIN {
    self->ts = walltimestamp;
}
demo$target:::printDemo
{
    @[arg1]=count();
}
END {
    self->ts = walltimestamp - self->ts;
    printf ("Total time used is (us): %d", (self->ts)/1000);
}

hello.c:
void printDemo(char *);
void printD(char *x)
{
    DTRACE_PROBE1(hello, printDemo, x);
}
int
main (void)
{
    long long x = 0;
    long long count = 187;
    for (x = 0; x < count; x++)
       {
        printD("Hello World");
       }
    printf("done %lld iterations\n", x);
}

The dtrace -G step gives you:
-    printD+0xc:          e8 fc ff ff ff     call   -0x4     <printD+0xd>
+    printD+0xc:          90                 nop
+    printD+0xd:          90                 nop
+    printD+0xe:          90                 nop
+    printD+0xf:          90                 nop
+    printD+0x10:         90                 nop

Now run it with probing turned on:
/usr/sbin/dtrace -Zqs ./hellotest_.d -c ./hello
done 187 iterations
Total time used is (us): 1020200


stap mockup:
all: tstlabel.x
stap-probes-tstlabel.c: tstlabel.d tstlabel.c
         python stap-probes.py $^
stap-probes-tstlabel.o: stap-probes-tstlabel.c
         $(CC) $^ -c -g
tstlabel.x: tstlabel.o stap-probes.o stap-probes-tstlabel.o
             $(CC) $^ -o $@
tstlabel.o: tstlabel.c stap-probes.h
             $(CC) tstlabel.c -c
stap-probes.o: stap-probes.c
             $(CC) $^ -c

tstlabel.d:
provider tstlabel {
    probe label1();
    probe label2();
    probe label3(int, char*);
};

tstlabel.c:
foo ()
{
   STAP_PROBE(tstlabel,label1);
}
bar ()
{
   STAP_PROBE(tstlabel,label2);
}
baz ()
{
   STAP_PROBE(tstlabel,label3);
}
main ()
{
   foo();
   bar();
   baz();

stap-probes.py generates tstlabel.c:
_stap_probe_label1 ()
{}
_stap_probe_label2 ()
{}
_stap_probe_label3 (int a, char* b)
{}

tstlabel.stp:
probe process.mark("label1")
{
printf("In label1 probe\n")
}
probe process.mark("label2")
{
printf("In label2 probe\n")
}
probe process.mark("label3")
{
printf("In label3 probe, but there are no args here\n")
}

stap -c /home/scox/stap/1918/tstlabel.x tstlabel.stp
In label1 probe
In label2 probe
In label3 probe, but there are no args here

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: static user probes
  2008-10-02 21:33 static user probes Stan Cox
@ 2008-10-02 21:43 ` Roland McGrath
       [not found]   ` <48E63A5B.5020202@redhat.com>
  2008-10-02 21:52 ` Roland McGrath
  2008-10-13  5:50 ` Maneesh Soni
  2 siblings, 1 reply; 8+ messages in thread
From: Roland McGrath @ 2008-10-02 21:43 UTC (permalink / raw)
  To: Stan Cox; +Cc: systemtap

> hello: helloprobes.o hello.o
>          $(CC) -o hello helloprobes.o hello.o
> helloprobes.o: hello.o
>          $(DTRACE) -G -s helloprobes.d hello.o
>          dis hello.o > hello.2.dis

Is this really how you have to do it?  This interposes dtrace into the
build process for each relocatable file.  I would have expected just one
post-processing step on the final executable.


Thanks,
Roland

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: static user probes
  2008-10-02 21:33 static user probes Stan Cox
  2008-10-02 21:43 ` Roland McGrath
@ 2008-10-02 21:52 ` Roland McGrath
  2008-10-03 20:22   ` Stan Cox
  2008-10-13  5:50 ` Maneesh Soni
  2 siblings, 1 reply; 8+ messages in thread
From: Roland McGrath @ 2008-10-02 21:52 UTC (permalink / raw)
  To: Stan Cox; +Cc: systemtap

> helloprobes.d:
> provider hello {
>     probe printDemo(char*);
> };

Is this part of dtrace script syntax, or is a "provider" file actually a
disjoint syntax only used by the static-prep tool?

What are the constraints on the types you can specify here?
Anything that goes in a C99 prototype?

In script language, what type does "arg1" have?  Is it just a scalar, or
could you do something to dereference that pointer?  If so, cna you do
something complex with e.g. struct types, etc.?


Thanks,
Roland

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: static user probes
  2008-10-02 21:52 ` Roland McGrath
@ 2008-10-03 20:22   ` Stan Cox
  0 siblings, 0 replies; 8+ messages in thread
From: Stan Cox @ 2008-10-03 20:22 UTC (permalink / raw)
  To: systemtap

Roland McGrath wrote:
>> helloprobes.d:
>> provider hello {
>>     probe printDemo(char*);
>> };
> 
> Is this part of dtrace script syntax, or is a "provider" file actually a
> disjoint syntax only used by the static-prep tool?

My understanding is that it is used as a static prep tool.
Collections of existing probes are known as providers, e.g. syscall 
provider, proc provider and pid provider.

> 
> What are the constraints on the types you can specify here?
> Anything that goes in a C99 prototype?
> 
> In script language, what type does "arg1" have?  Is it just a scalar, or
> could you do something to dereference that pointer?  

Based on what I have read for anything other than integer arguments I 
believe that it is necessary to use the copyin() or copyinstr() 
subroutines to dereference the pointer.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: static user probes
       [not found]   ` <48E63A5B.5020202@redhat.com>
@ 2008-10-03 20:29     ` Stan Cox
  2008-10-03 20:39       ` Stan Cox
  0 siblings, 1 reply; 8+ messages in thread
From: Stan Cox @ 2008-10-03 20:29 UTC (permalink / raw)
  To: systemtap

Stan Cox wrote:
> Roland McGrath wrote:
> 
> Is this really how you have to do it?  This interposes dtrace into the
> build process for each relocatable file.  I would have expected just one
> post-processing step on the final executable.

That is the process described at:
   http://docs.sun.com/app/docs/doc/817-6223/6mlkidls5?l=en&a=view
  It modifies the call to the probes in the object files, leaving space
  for reinsertion.   hello.gcc.o is from 'gcc hello.c' and
  hello.dtrace.o/helloprobes.o are from 'dtrace -G -s helloprobes.d hello.o'


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: static user probes
  2008-10-03 20:29     ` Stan Cox
@ 2008-10-03 20:39       ` Stan Cox
  0 siblings, 0 replies; 8+ messages in thread
From: Stan Cox @ 2008-10-03 20:39 UTC (permalink / raw)
  To: systemtap

[-- Attachment #1: Type: text/plain, Size: 123 bytes --]


>  hello.gcc.o is from 'gcc hello.c' and
>  hello.dtrace.o/helloprobes.o are from 'dtrace -G -s helloprobes.d hello.o'




[-- Attachment #2: hello.tbz --]
[-- Type: application/x-bzip-compressed-tar, Size: 3631 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: static user probes
  2008-10-02 21:33 static user probes Stan Cox
  2008-10-02 21:43 ` Roland McGrath
  2008-10-02 21:52 ` Roland McGrath
@ 2008-10-13  5:50 ` Maneesh Soni
  2008-10-14 21:40   ` Stan Cox
  2 siblings, 1 reply; 8+ messages in thread
From: Maneesh Soni @ 2008-10-13  5:50 UTC (permalink / raw)
  To: Stan Cox; +Cc: systemtap

On Thu, Oct 02, 2008 at 05:32:23PM -0400, Stan Cox wrote:
[..]
> stap mockup:
> all: tstlabel.x
> stap-probes-tstlabel.c: tstlabel.d tstlabel.c
>         python stap-probes.py $^
> stap-probes-tstlabel.o: stap-probes-tstlabel.c
>         $(CC) $^ -c -g
> tstlabel.x: tstlabel.o stap-probes.o stap-probes-tstlabel.o
>             $(CC) $^ -o $@
> tstlabel.o: tstlabel.c stap-probes.h
>             $(CC) tstlabel.c -c
> stap-probes.o: stap-probes.c
>             $(CC) $^ -c
>

Which is stap-probes.c file and why is this required?

> tstlabel.d:
> provider tstlabel {
>    probe label1();
>    probe label2();
>    probe label3(int, char*);
> };
>

Is this .d file written by the user or generated automatically?
what is the use of it?

> tstlabel.c:
> foo ()
> {
>   STAP_PROBE(tstlabel,label1);
> }
> bar ()
> {
>   STAP_PROBE(tstlabel,label2);
> }
> baz ()
> {
>   STAP_PROBE(tstlabel,label3);
> }
> main ()
> {
>   foo();
>   bar();
>   baz();
>
> stap-probes.py generates tstlabel.c:

Do you mean, stap-probes-tstlable.c? Could you also share the .py?

> _stap_probe_label1 ()
> {}
> _stap_probe_label2 ()
> {}
> _stap_probe_label3 (int a, char* b)
> {}
>

Thanks
Maneesh

-- 
Maneesh Soni
Linux Technology Center
IBM India Systems and Technology Lab,
Bangalore, India.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: static user probes
  2008-10-13  5:50 ` Maneesh Soni
@ 2008-10-14 21:40   ` Stan Cox
  0 siblings, 0 replies; 8+ messages in thread
From: Stan Cox @ 2008-10-14 21:40 UTC (permalink / raw)
  To: maneesh; +Cc: systemtap

[-- Attachment #1: Type: text/plain, Size: 1643 bytes --]

Maneesh Soni wrote:

> Which is stap-probes.c file and why is this required?

That is just an editing problem.  It isn't required

> Is this .d file written by the user or generated automatically?
> what is the use of it?

It is written by the user and describes the argument signature for the 
probes.

> Do you mean, stap-probes-tstlable.c? Could you also share the .py?

Sure.  Here is an stap example which will now hit a probe and print 
arguments and also the python script.

***** cat tstlabel.c *****  test program
#include <stdlib.h>
#include "stap-probes.h"

foo ()
{
   STAP_PROBE(tstlabel,label1);
}

bar (int i)
{
   STAP_PROBE(tstlabel,label2,i);
}

baz (int i, char* s)
{
   STAP_PROBE(tstlabel,label3,i,s);
}

main ()
{
   foo();
   bar(2);
   baz(3,"abc");
}

***** cat stap-probes.h ***** marker include file
#define STAP_PROBE(provider,probe,...)        \
   _stap_probe_ ## probe (__VA_ARGS__);

***** cat tstlabel.d ***** used to create stap-probes-tstlabel.c
provider tstlabel {
    probe label1();
    probe label2(int);
    probe label3(int, char*);
};


***** cat stap-probes-tstlabel.c ***** currently, a generated file
_stap_probe_label1 ()
{
    return 1;
}

_stap_probe_label2 (int a)
{
    return 1;
}

_stap_probe_label3 (int a, char* b)
{
    return 1;
}

***** cat 19180.stp ***** script to test above
probe process.mark("label1")
{
    printf("label3\n")
}

probe process.mark("label2")
{
    printf("label3 arg1=%d\n", $a)
}
probe process.mark("label3")
{
    printf("label3 arg1=%d arg2=%#x\n", $a, $b)
}


stap -c /home/scox/stap/1918/tstlabel.x 19180.stp
label1
label2 arg1=2
label3 arg1=3 arg2=0x4005e8


[-- Attachment #2: stap-probes.py --]
[-- Type: text/x-python, Size: 2903 bytes --]

import sys

class provider:
    arglist = dict()
    def open(self, provider):
        self.f = open(provider)
        while (True):
            line = self.f.readline()
            if (line == ""):
                break
            if (line.find("provider") > 0):
                tokens = line.split()
                self.provider = tokens[1]
            elif (line.find("probe") > 0):
                this_probe = line[line.find("probe ")+5:line.find("(")].strip()
                args = (line[line.find("(")+1:line.find(")")])
                new_args = ""
                i = 0
                c = 0
                letters = "abcdefghijklmnopqrstuvwxyz"
                while (i < len(args)):
                    if (args[i:i+1] == ","):
                        new_args = new_args + " " + letters[c] + args[i]
                        c += 1
                    else:
                        new_args = new_args + args[i]
                    i += 1
                if (len(args) > 0):
                    self.arglist[this_probe] = new_args + " " + letters[c]
    def get(self, arg):
        print arg
        if (arg in self.arglist):
            return self.arglist[arg]
        else:
            return ""

class probe:
    isopen = False
    def open(self, provider):
        if (not self.isopen):
            self.f = open("stap-probes-" + provider + ".c", "w")
        self.isopen = True
    def add(self, probe, arglist):
        self.f.write("_stap_probe_" + probe + " (" + arglist + ")\n")
        self.f.write("{\n   return 1;\n}\n\n")
    def close(self, fn):
        self.f.close()

########################################################################
# main
########################################################################

def usage ():
    print "Usage " + sys.argv[0] + " File.d File.c <File.c>..."
    sys.exit(1)

def open_file (arg):
    if (len (sys.argv) <= arg):
        return False
    try:
        file = open(sys.argv[arg], 'r')
    except IOError:
        print (sys.argv[arg] + " not found")
        sys.exit(1)
    return file

if (len (sys.argv) < 3):
    usage()

providers = provider()
providers.open(sys.argv[1])

current_file = 2
d_file = open_file(current_file)
filename = sys.argv[current_file]
p_file = probe()

while (True):
    line = d_file.readline()
    if (line == ""):
        current_file += 1
        d_file = open_file(current_file)
        if (not d_file):
            break
    if (line.find("STAP_PROBE") > 0):
        p_file.open(line[line.find("(")+1:line.find(",")])
        partial_line=line[line.find(",")+1:]
        print partial_line
        comma = partial_line.find(",")
        rparen = partial_line.find(")")
        if (comma == -1):
            token_end = rparen
        else:
            token_end = comma
        this_probe = partial_line[0:token_end].strip()
        p_file.add(this_probe,providers.get(this_probe))


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2008-10-14 21:40 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-10-02 21:33 static user probes Stan Cox
2008-10-02 21:43 ` Roland McGrath
     [not found]   ` <48E63A5B.5020202@redhat.com>
2008-10-03 20:29     ` Stan Cox
2008-10-03 20:39       ` Stan Cox
2008-10-02 21:52 ` Roland McGrath
2008-10-03 20:22   ` Stan Cox
2008-10-13  5:50 ` Maneesh Soni
2008-10-14 21:40   ` Stan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).