[lttng-dev] [PATCH] Create the lttng-gen-tp tools as an helper to generate UST .h and .c files

Mathieu Desnoyers mathieu.desnoyers at efficios.com
Thu Feb 16 06:24:55 EST 2012


* Yannick Brosseau (yannick.brosseau at gmail.com) wrote:
> Based on a template file which contains TRACEPOINT_EVENT definition, the
> tools generate the necessary .h and .c to create the probes.
> 
> Include an example use in tests/gen-tp/
> 
> (refs #24)
> 
> Signed-off-by: Yannick Brosseau <yannick.brosseau at gmail.com>
> ---
>  Makefile.am                       |    1 +
>  configure.ac                      |    1 +
>  tests/gen-tp/Makefile             |   41 +++++++
>  tests/gen-tp/sample.c             |   27 +++++
>  tests/gen-tp/sample_tracepoint.tp |   15 +++
>  tools/Makefile.am                 |    2 +
>  tools/lttng-gen-tp                |  214 +++++++++++++++++++++++++++++++++++++
>  7 files changed, 301 insertions(+), 0 deletions(-)
>  create mode 100644 tests/gen-tp/Makefile
>  create mode 100644 tests/gen-tp/sample.c
>  create mode 100644 tests/gen-tp/sample_tracepoint.tp
>  create mode 100644 tools/Makefile.am
>  create mode 100755 tools/lttng-gen-tp
> 
> diff --git a/Makefile.am b/Makefile.am
> index 8aff58d..bc2f442 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -5,6 +5,7 @@ SUBDIRS = . include snprintf libringbuffer liblttng-ust-comm \
>  		liblttng-ust-ctl \
>  		liblttng-ust-fork \
>  		liblttng-ust-libc-wrapper \
> +		tools \
>  		tests
>  
>  if BUILD_JNI_INTERFACE
> diff --git a/configure.ac b/configure.ac
> index 63f13d0..1b96b4e 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -263,6 +263,7 @@ AC_CONFIG_FILES([
>  	liblttng-ust-fork/Makefile
>  	liblttng-ust-java/Makefile
>  	liblttng-ust-libc-wrapper/Makefile
> +	tools/Makefile
>  	tests/Makefile
>  	tests/hello/Makefile
>  	tests/hello-static-lib/Makefile
> diff --git a/tests/gen-tp/Makefile b/tests/gen-tp/Makefile
> new file mode 100644
> index 0000000..9278ebf
> --- /dev/null
> +++ b/tests/gen-tp/Makefile
> @@ -0,0 +1,41 @@
> +# Copyright (C) 2011-2012  Matthew Khouzam <matthew.khouzam at ericsson.com> 
> +# Copyright (C) 2012  Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
> +# Copyright (C) 2012  Yannick Brosseau <yannick.brosseau at gmail.com>
> +#
> +# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
> +# OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
> +#
> +# Permission is hereby granted to use or copy this program for any
> +# purpose,  provided the above notices are retained on all copies.
> +# Permission to modify the code and to distribute modified code is
> +# granted, provided the above notices are retained, and a notice that
> +# the code was modified is included with the above copyright notice.
> +
> +# This makefile is not using automake so that people can see how to make
> +# simply. It builds a program with a statically embedded tracepoint
> +# provider probe.
> +
> +CC = gcc
> +LIBS = -ldl -llttng-ust
> +
> +all: sample
> +
> +sample: sample.o sample-tp.o
> +	$(CC) $(LIBS) -o $@ $^
> +
> +sample.o: sample.c sample_tracepoint.h
> +	$(CC) $(CFLAGS) -c -o $@ $<
> +
> +sample-tp.o: sample_tracepoint.c sample_tracepoint.h
> +	$(CC) $(CFLAGS) -I. -c -o $@ $< 
> +
> +%.h: %.tp
> +	lttng-gen-tp -o $@ $<
> +%.c: %.tp
> +	lttng-gen-tp -o $@ $<
> +
> +
> +.PHONY: clean
> +clean:
> +	rm -f *.o sample
> +	rm -f sample_tracepoint.h sample_tracepoint.c
> diff --git a/tests/gen-tp/sample.c b/tests/gen-tp/sample.c
> new file mode 100644
> index 0000000..c189b3f
> --- /dev/null
> +++ b/tests/gen-tp/sample.c
> @@ -0,0 +1,27 @@
> +/*
> + * Copyright (C) 2011-2012  Matthew Khouzam <matthew.khouzam at ericsson.com> 
> + * Copyright (C) 2012  Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
> + *#

Forgot to remove a #

> + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
> + * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
> + *
> + * Permission is hereby granted to use or copy this program for any
> + * purpose,  provided the above notices are retained on all copies.
> + * Permission to modify the code and to distribute modified code is
> + * granted, provided the above notices are retained, and a notice that
> + * the code was modified is included with the above copyright notice.
> + */
> + 

whitespaces are left in many locations. Please use scripts/checkpatch.pl
from the Linux source tree.

> +#include <unistd.h>
> +
> +#include "sample_tracepoint.h"
> +int main(int argc, char **argv)
> +{
> +	int i = 0;
> +
> +	for (i = 0; i < 100000; i++) {
> +		tracepoint(sample_tracepoint, message,  "Hello World\n");
> +		usleep(1);
> +	}
> +	return 0;
> +}
> diff --git a/tests/gen-tp/sample_tracepoint.tp b/tests/gen-tp/sample_tracepoint.tp
> new file mode 100644
> index 0000000..9e6857a
> --- /dev/null
> +++ b/tests/gen-tp/sample_tracepoint.tp
> @@ -0,0 +1,15 @@
> +TRACEPOINT_EVENT(
> +	sample_tracepoint,
> +	message, // C++ Style comment
> +	TP_ARGS(char *, text),
> +	TP_FIELDS(
> +		ctf_string(message, text)
> +		  )
> +)
> +/* 
> + * Longer comments
> + */
> +TRACEPOINT_LOGLEVEL(
> +	sample_tracepoint, 
> +	message, 
> +	TRACE_WARNING)
> diff --git a/tools/Makefile.am b/tools/Makefile.am
> new file mode 100644
> index 0000000..f0ee493
> --- /dev/null
> +++ b/tools/Makefile.am
> @@ -0,0 +1,2 @@
> +
> +dist_bin_SCRIPTS = lttng-gen-tp
> \ No newline at end of file
> diff --git a/tools/lttng-gen-tp b/tools/lttng-gen-tp
> new file mode 100755
> index 0000000..32014b0
> --- /dev/null
> +++ b/tools/lttng-gen-tp
> @@ -0,0 +1,214 @@
> +#!/usr/bin/python
> +#
> +# Copyright (c)  2012 Yannick Brosseau <yannick.brosseau at gmail.com>
> +#
> +# This program is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU General Public License
> +# as published by the Free Software Foundation; only version 2
> +# of the License.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License along
> +# with this program; if not, write to the Free Software Foundation, Inc.,
> +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> +
> +import sys
> +import getopt
> +import re
> +
> +class Usage(Exception):
> +    def __init__(self, msg):
> +        self.msg = msg
> +
> +class HeaderFile:
> +    HEADER_TPL="""
> +#undef TRACEPOINT_PROVIDER
> +#define TRACEPOINT_PROVIDER {providerName}
> +
> +#undef TRACEPOINT_INCLUDE_FILE
> +#define TRACEPOINT_INCLUDE_FILE ./{headerFilename}
> +
> +#ifdef __cplusplus
> +#extern "C"{{
> +#endif /*__cplusplus */
> +
> +
> +#if !defined({includeGuard}) || defined(TRACEPOINT_HEADER_MULTI_READ)
> +#define {includeGuard}
> +
> +#include <lttng/tracepoint.h> 
> +
> +"""
> +    FOOTER_TPL="""
> +#endif /* {includeGuard} */
> +
> +#include <lttng/tracepoint-event.h>
> +
> +#ifdef __cplusplus
> +}}
> +#endif /*__cplusplus */
> +
> +"""
> +    def __init__(self, filename, template):
> +        self.outputFilename = filename
> +        self.template = template
> +
> +    def write(self):
> +        outputFile = open(self.outputFilename,"w")
> +        includeGuard = "_"+self.outputFilename.upper().replace(".","_")
> +        
> +        outputFile.write(HeaderFile.HEADER_TPL.format(providerName=self.template.domain,
> +                                           includeGuard = includeGuard,
> +                                           headerFilename = self.outputFilename))
> +        outputFile.write(self.template.text)
> +        outputFile.write(HeaderFile.FOOTER_TPL.format(includeGuard = includeGuard))
> +        outputFile.close()
> +
> +class CFile:
> +    FILE_TPL="""
> +#define TRACEPOINT_CREATE_PROBES
> +/*
> + * The header containing our TRACEPOINT_EVENTs. 
> + */
> +#define TRACEPOINT_DEFINE
> +#include "{headerFilename}"
> +"""
> +    def __init__(self, filename, template):
> +        self.outputFilename = filename
> +        self.template = template
> +
> +    def write(self):
> +        outputFile = open(self.outputFilename,"w")
> +
> +        headerFilename = self.outputFilename.replace(".c",".h")
> +
> +        outputFile.write(CFile.FILE_TPL.format(
> +                                           headerFilename = headerFilename))
> +        outputFile.close()
> +
> +class TemplateFile:
> +    def __init__(self, filename):
> +        self.domain = ""
> +        self.inputFilename = filename
> +        self.parseTemplate()
> +
> +
> +    def parseTemplate(self):
> +        f = open(self.inputFilename,"r")
> +
> +        self.text = f.read()
> +
> +        #Remove # comments (from input and output file
> +        self.text = re.sub("#.*$","",self.text,flags=re.MULTILINE)
> +        #Remove // comments
> +        nolinecomment = re.sub("\/\/.*$","",self.text,flags=re.MULTILINE)
> +        #Remove all spaces and lines
> +        cleantext = re.sub("\s*","",nolinecomment)
> +        #Remove multine C style comments
> +        nocomment = re.sub("/\*.*?\*/","",cleantext)
> +        entries = re.split("TRACEPOINT_.*?",nocomment)
> +
> +        for entry in entries:
> +            if entry != '':
> +                decomp = re.findall("(\w*?)\((\w*?),(\w*?),", entry)
> +                typea = decomp[0][0]
> +                domain = decomp[0][1]
> +                name = decomp[0][2]
> +
> +                if self.domain == "":
> +                    self.domain = domain
> +                else:
> +                    if self.domain != domain:
> +                        print "Warning: different domain provided (%s,%s)" % (self.domain, domain)
> + 
> +
> +usage="""
> + lttng-gen-tp - Generate the LTTng-UST header and source based on a simple template
> +
> + usage: lttng-gen-tp TEMPLATE_FILE [-o OUTPUT_FILE]
> +
> + If no OUTPUT_FILE is given, the .h and .c file will be generated. 
> + (The basename of the template file with be used for the generated file. 
> +  for example sample.tp will generate sample.h and sample.c) 
> +
> + When using the -o option, the OUTPUT_FILE must end with either .h or .c

Will it just generate either the .h or .c if specified ?

Is it OK to specify a .o output file ? Or .a, or .so ?

> +
> + The template file must contains TRACEPOINT_EVENT and TRACEPOINT_LOGLEVEL 
> + as per defined in the lttng/tracepoint.h file. 
> + See the man page for more detail. 

You could refer to the upcoming lttng-ust(3) man page.

Thanks,

Mathieu

> +"""
> +def main(argv=None):
> +    if argv is None:
> +        argv = sys.argv
> +
> +    try:
> +        try:
> +            opts, args = getopt.gnu_getopt(argv[1:], "ho:a", ["help"])
> +        except getopt.error, msg:
> +             raise Usage(msg)
> +        
> +    except Usage, err:
> +        print >>sys.stderr, err.msg
> +        print >>sys.stderr, "for help use --help"
> +        return 2
> +
> +    outputName = ""
> +    for o, a in opts:
> +        if o in ("-h", "--help"):
> +            print usage
> +            return(0)
> +        if o in ("-o",""):
> +            outputName = a
> +        if o in ("-a",""):
> +            all = True
> +
> +    doCFile = None
> +    doHeader = None
> +    headerFilename = None
> +    cFilename = None            
> +
> +    if outputName is not "":
> +        if len(args) > 1:
> +            print "Cannot process more than one input if you specify an output"
> +            return(3)
> +    
> +        if outputName[-2:] == ".h":
> +            doHeader = True
> +            headerFilename = outputName
> +        elif outputName[-2:] == ".c":
> +            doCFile = True
> +            cFilename = outputName
> +        elif outputName[-2:] == ".o":
> +            pass
> +        else:
> +            print "output file type unsupported"
> +            return(4)
> +    else:
> +        doHeader = True
> +        doCFile = True
> +
> +    # process arguments
> +    for arg in args:
> +
> +        tpl = TemplateFile(arg)
> +        if doHeader:
> +            if headerFilename:
> +                curFilename = headerFilename
> +            else:
> +                curFilename = re.sub("\.tp$",".h",arg)
> +            doth = HeaderFile(curFilename, tpl)
> +            doth.write()
> +        if doCFile:
> +            if cFilename:
> +                curFilename = cFilename
> +            else:
> +                curFilename = re.sub("\.tp$",".c",arg)
> +            dotc = CFile(curFilename, tpl)
> +            dotc.write()
> +
> +if __name__ == "__main__":
> +    sys.exit(main())
> -- 
> 1.7.9
> 
> 
> _______________________________________________
> lttng-dev mailing list
> lttng-dev at lists.lttng.org
> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

-- 
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com



More information about the lttng-dev mailing list