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

Yannick Brosseau yannick.brosseau at gmail.com
Wed Feb 15 23:57:30 EST 2012


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>
+ *#
+ * 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.
+ */
+ 
+#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
+
+ 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. 
+"""
+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




More information about the lttng-dev mailing list