From b25c5b37ef536d7b09fe901d97e678220ec69c9a Mon Sep 17 00:00:00 2001 From: Yannick Brosseau Date: Thu, 16 Feb 2012 09:11:11 -0500 Subject: [PATCH] Create the lttng-gen-tp tools as an helper to generate UST .h and .c files 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 Signed-off-by: Mathieu Desnoyers --- Makefile.am | 1 + configure.ac | 1 + tests/gen-tp/Makefile | 40 ++++++ tests/gen-tp/sample.c | 26 ++++ tests/gen-tp/sample_tracepoint.tp | 15 +++ tools/Makefile.am | 1 + tools/lttng-gen-tp | 215 ++++++++++++++++++++++++++++++ 7 files changed, 299 insertions(+) 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 100644 tools/lttng-gen-tp diff --git a/Makefile.am b/Makefile.am index 8aff58db..bc2f4420 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 d04f4322..9c452708 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 00000000..664372f2 --- /dev/null +++ b/tests/gen-tp/Makefile @@ -0,0 +1,40 @@ +# Copyright (C) 2011-2012 Matthew Khouzam +# Copyright (C) 2012 Mathieu Desnoyers +# Copyright (C) 2012 Yannick Brosseau +# +# 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 00000000..729258c2 --- /dev/null +++ b/tests/gen-tp/sample.c @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011-2012 Matthew Khouzam + * Copyright (C) 2012 Mathieu Desnoyers + * + * 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 + +#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 00000000..fa7d18a5 --- /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 00000000..4ea75331 --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1 @@ +dist_bin_SCRIPTS = lttng-gen-tp diff --git a/tools/lttng-gen-tp b/tools/lttng-gen-tp new file mode 100644 index 00000000..9b082755 --- /dev/null +++ b/tools/lttng-gen-tp @@ -0,0 +1,215 @@ +#!/usr/bin/python +# +# Copyright (c) 2012 Yannick Brosseau +# +# 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 + +""" + FOOTER_TPL=""" +#endif /* {includeGuard} */ + +#include + +#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][-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 -o option can be repeated multiple times. + + The template file must contains TRACEPOINT_EVENT and TRACEPOINT_LOGLEVEL + as per defined in the lttng/tracepoint.h file. + See the lttng-ust(3) man page for more details on the format. +""" +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 + + outputNames = [] + for o, a in opts: + if o in ("-h", "--help"): + print usage + return(0) + if o in ("-o",""): + outputNames.append(a) + if o in ("-a",""): + all = True + + doCFile = None + doHeader = None + headerFilename = None + cFilename = None + + if len(outputNames) > 0: + if len(args) > 1: + print "Cannot process more than one input if you specify an output" + return(3) + + for outputName in outputNames: + if outputName[-2:] == ".h": + doHeader = True + headerFilename = outputName + elif outputName[-2:] == ".c": + doCFile = True + cFilename = outputName + elif outputName[-2:] == ".o": + print "Not yet implemented, sorry" + 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()) -- 2.34.1