<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Tahoma
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>
<br><br><div><div id="SkyDrivePlaceholder"></div>> Date: Tue, 31 Jul 2012 14:43:05 -0400<br>> From: david.goulet@polymtl.ca<br>> To: danny.serres@efficios.com<br>> CC: lttng-dev@lists.lttng.org<br>> Subject: Re: [lttng-dev] [lttng-tools PATCH] lttng-tools python module<br>> <br>> -----BEGIN PGP SIGNED MESSAGE-----<br>> Hash: SHA1<br>> <br>> Hi Danny,<br>> <br>> Sorry for the delay!<br>> <br>> First, thanks for this great work. I have a couple of "requests" before I put<br>> all that upstream.<br>> <br>> Can you add the generated files into .gitignore please. I get this:<br>> <br>> #    src/python/lttng.i<br>> #      src/python/lttng.py<br>> #     src/python/lttng_wrap.c<br>> <br>> There is also forgotten whitespaces in src/python/lttng.i.in (first carac.)<br>> <br>> +               char *__repr__() {<br>> (times 5)<br><br>Fixed<br><br>> <br>> Apart from those minor issues, I have two questions about this patch. First,<br>> why is the python module in src/ and not in extras/ ? I consider src/ to be<br>> supported and stable code shipped with the installation and/or in packages.<br>> Also, the src/ directory is the core code of lttng-tools and this module is<br>> more an extra useful tool.<br>> <br>> Second, _IF_ this goes into src/, please move the tests to the tests/<br>> directory else we are going to make it self contained in extras/ which is good<br>> right now.<br>> <br><br>From what I've seen so far, other projects all have a top python dir which includes<br>the Python-related file.  I'll wait on approval on doing this before posting a new version.<br><br>> Last thing, could it be possible to have a small how-to/tutorial in the doc/<br>> directory so people know that this exist and how to install it and use it ?<br>> (Also add it to the README in PACKAGE CONTENTS). A swig2 dependency will be<br>> added with this module so this howto should mention that this depends on that<br>> software. (swig2.0 package on Debian/Ubuntu).<br>> <br>Done<br><br>Thanks<br>Danny<br><br>> I might be wrong on some point so don't hesitate to argue and comment! :)<br>> <br>> Cheers!<br>> David<br>> <br>> On 26/07/12 02:09 PM, Danny Serres wrote:<br>> > The lttng-tools Python module can be used to directly control the<br>> > lttng-tools API inside Python, using 'import lttng'.<br>> > <br>> > Therefore, it becomes possible to create a trace, add events, start/stop<br>> > tracing, destroy a session and so on from within Python.<br>> > <br>> > The module does not include URI-related functions.<br>> > <br>> > SWIG >= 2.0 is used to create the wrapper and its 'warning md variable<br>> > unused' bug is patched in Makefile.am.<br>> > <br>> > In the interface file, struct and enum are directly copied from lttng.h<br>> > (all changes must be made in both files).<br>> > <br>> > Signed-off-by: Danny Serres <danny.serres@efficios.com> Signed-off-by:<br>> > Yannick Brosseau <yannick.brosseau@gmail.com> --- config/ax_pkg_swig.m4<br>> > |  135 ++++++ configure.ac                |   43 ++ src/Makefile.am<br>> > |    4 + src/python/Makefile.am      |   25 ++ src/python/lttng.i.in<br>> > | 1023 +++++++++++++++++++++++++++++++++++++++++++ <br>> > src/python/tests/example.py |  109 +++++ src/python/tests/run.sh     |    1<br>> > + src/python/tests/tests.py   |  310 +++++++++++++ 8 files changed, 1650<br>> > insertions(+) create mode 100644 config/ax_pkg_swig.m4 create mode 100644<br>> > src/python/Makefile.am create mode 100644 src/python/lttng.i.in create mode<br>> > 100644 src/python/tests/example.py create mode 100644<br>> > src/python/tests/run.sh create mode 100644 src/python/tests/tests.py<br>> > <br>> > diff --git a/config/ax_pkg_swig.m4 b/config/ax_pkg_swig.m4 new file mode<br>> > 100644 index 0000000..e112f3d --- /dev/null +++ b/config/ax_pkg_swig.m4 @@<br>> > -0,0 +1,135 @@ +#<br>> > ===========================================================================<br>> ><br>> > <br>> +#        http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html<br>> > +#<br>> > ===========================================================================<br>> ><br>> > <br>> +#<br>> > +# SYNOPSIS +# +#   AX_PKG_SWIG([major.minor.micro], [action-if-found],<br>> > [action-if-not-found]) +# +# DESCRIPTION +# +#   This macro searches for a<br>> > SWIG installation on your system. If found, +#   then SWIG is AC_SUBST'd;<br>> > if not found, then $SWIG is empty.  If SWIG is +#   found, then SWIG_LIB is<br>> > set to the SWIG library path, and AC_SUBST'd. +# +#   You can use the<br>> > optional first argument to check if the version of the +#   available SWIG<br>> > is greater than or equal to the value of the argument. It +#   should have<br>> > the format: N[.N[.N]] (N is a number between 0 and 999. Only +#   the first<br>> > N is mandatory.) If the version argument is given (e.g. +#   1.3.17),<br>> > AX_PKG_SWIG checks that the swig package is this version number +#   or<br>> > higher. +# +#   As usual, action-if-found is executed if SWIG is found,<br>> > otherwise +#   action-if-not-found is executed. +# +#   In configure.in,<br>> > use as: +# +#     AX_PKG_SWIG(1.3.17, [], [ AC_MSG_ERROR([SWIG is required<br>> > to build..]) ]) +#     AX_SWIG_ENABLE_CXX +#<br>> > AX_SWIG_MULTI_MODULE_SUPPORT +#     AX_SWIG_PYTHON +# +# LICENSE +# +#<br>> > Copyright (c) 2008 Sebastian Huber <sebastian-huber@web.de> +#   Copyright<br>> > (c) 2008 Alan W. Irwin <irwin@beluga.phys.uvic.ca> +#   Copyright (c) 2008<br>> > Rafael Laboissiere <rafael@laboissiere.net> +#   Copyright (c) 2008 Andrew<br>> > Collier <colliera@ukzn.ac.za> +#   Copyright (c) 2011 Murray Cumming<br>> > <murrayc@openismus.com> +# +#   This program is free software; you can<br>> > redistribute it and/or modify it +#   under the terms of the GNU General<br>> > Public License as published by the +#   Free Software Foundation; either<br>> > version 2 of the License, or (at your +#   option) any later version. +# +#<br>> > This program is distributed in the hope that it will be useful, but +#<br>> > WITHOUT ANY WARRANTY; without even the implied warranty of +#<br>> > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +#<br>> > Public License for more details. +# +#   You should have received a copy of<br>> > the GNU General Public License along +#   with this program. If not, see<br>> > <http://www.gnu.org/licenses/>. +# +#   As a special exception, the<br>> > respective Autoconf Macro's copyright owner +#   gives unlimited permission<br>> > to copy, distribute and modify the configure +#   scripts that are the<br>> > output of Autoconf when processing the Macro. You +#   need not follow the<br>> > terms of the GNU General Public License when using +#   or distributing<br>> > such scripts, even though portions of the text of the +#   Macro appear in<br>> > them. The GNU General Public License (GPL) does govern +#   all other use<br>> > of the material that constitutes the Autoconf Macro. +# +#   This special<br>> > exception to the GPL applies to versions of the Autoconf +#   Macro<br>> > released by the Autoconf Archive. When you make and distribute a +#<br>> > modified version of the Autoconf Macro, you may extend this special +#<br>> > exception to the GPL to apply to your modified version as well. + +#serial<br>> > 8 + +AC_DEFUN([AX_PKG_SWIG],[ +        # Ubuntu has swig 2.0 as<br>> > /usr/bin/swig2.0 +        AC_PATH_PROGS([SWIG],[swig swig2.0]) +        if<br>> > test -z "$SWIG" ; then +                m4_ifval([$3],[$3],[:]) +<br>> > elif test -n "$1" ; then +                AC_MSG_CHECKING([SWIG version]) +<br>> > [swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed<br>> > 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`] +<br>> > AC_MSG_RESULT([$swig_version]) +                if test -n "$swig_version"<br>> > ; then +                        # Calculate the required version number<br>> > components +                        [required=$1] +<br>> > [required_major=`echo $required | sed 's/[^0-9].*//'`] +<br>> > if test -z "$required_major" ; then +<br>> > [required_major=0] +                        fi +<br>> > [required=`echo $required | sed 's/[0-9]*[^0-9]//'`] +<br>> > [required_minor=`echo $required | sed 's/[^0-9].*//'`] +<br>> > if test -z "$required_minor" ; then +<br>> > [required_minor=0] +                        fi +<br>> > [required=`echo $required | sed 's/[0-9]*[^0-9]//'`] +<br>> > [required_patch=`echo $required | sed 's/[^0-9].*//'`] +<br>> > if test -z "$required_patch" ; then +<br>> > [required_patch=0] +                        fi +                        #<br>> > Calculate the available version number components +<br>> > [available=$swig_version] +                        [available_major=`echo<br>> > $available | sed 's/[^0-9].*//'`] +                        if test -z<br>> > "$available_major" ; then +<br>> > [available_major=0] +                        fi +<br>> > [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] +<br>> > [available_minor=`echo $available | sed 's/[^0-9].*//'`] +<br>> > if test -z "$available_minor" ; then +<br>> > [available_minor=0] +                        fi +<br>> > [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] +<br>> > [available_patch=`echo $available | sed 's/[^0-9].*//'`] +<br>> > if test -z "$available_patch" ; then +<br>> > [available_patch=0] +                        fi +                        #<br>> > Convert the version tuple into a single number for easier comparison. +<br>> > # Using base 100 should be safe since SWIG internally uses BCD values +<br>> > # to encode its version number. +<br>> > required_swig_vernum=`expr $required_major \* 10000 \ +<br>> > \+ $required_minor \* 100 \+ $required_patch` +<br>> > available_swig_vernum=`expr $available_major \* 10000 \ +<br>> > \+ $available_minor \* 100 \+ $available_patch` + +<br>> > if test $available_swig_vernum -lt $required_swig_vernum; then +<br>> > AC_MSG_WARN([SWIG version >= $1 is required.  You have $swig_version.]) +<br>> > SWIG='' +                                m4_ifval([$3],[$3],[]) +<br>> > else +                                AC_MSG_CHECKING([for SWIG library]) +<br>> > SWIG_LIB=`$SWIG -swiglib` +<br>> > AC_MSG_RESULT([$SWIG_LIB]) +<br>> > m4_ifval([$2],[$2],[]) +                        fi +                else +<br>> > AC_MSG_WARN([cannot determine SWIG version]) +<br>> > SWIG='' +                        m4_ifval([$3],[$3],[]) +<br>> > fi +        fi +        AC_SUBST([SWIG_LIB]) +]) diff --git a/configure.ac<br>> > b/configure.ac index 17e6b67..97167de 100644 --- a/configure.ac +++<br>> > b/configure.ac @@ -154,6 +154,40 @@ AC_CHECK_LIB([c], [open_memstream], ] <br>> > )<br>> > <br>> > +# For Python +# SWIG version needed or newer: +swig_version=2.0.0 + <br>> > +AC_ARG_ENABLE([python], +<br>> > [AC_HELP_STRING([--disable-python], +                              [do not<br>> > compile Python bindings])], +              [], [enable_python=yes]) + <br>> > +AM_CONDITIONAL([USE_PYTHON], [test "x${enable_python:-yes}" = xyes]) + +if<br>> > test "x${enable_python:-yes}" = xyes; then +  AC_MSG_NOTICE([You may<br>> > configure with --disable-python ]dnl +[if you do not need Python<br>> > bindings.]) + +  AX_PKG_SWIG($swig_version, [], [ AC_MSG_ERROR([SWIG<br>> > $swig_version or newer is needed]) ]) +  AM_PATH_PYTHON + +<br>> > AC_ARG_VAR([PYTHON_INCLUDE], [Include flags for python, bypassing<br>> > python-config]) +  AC_ARG_VAR([PYTHON_CONFIG], [Path to python-config]) +<br>> > AS_IF([test -z "$PYTHON_INCLUDE"], [ +    AS_IF([test -z "$PYTHON_CONFIG"],<br>> > [ +      AC_PATH_PROGS([PYTHON_CONFIG], +<br>> > [python$PYTHON_VERSION-config python-config], +                    [no], +<br>> > [`dirname $PYTHON`]) +      AS_IF([test "$PYTHON_CONFIG" = no],<br>> > [AC_MSG_ERROR([cannot find python-config for $PYTHON.])]) +    ]) +<br>> > AC_MSG_CHECKING([python include flags]) +    PYTHON_INCLUDE=`$PYTHON_CONFIG<br>> > --includes` +    AC_MSG_RESULT([$PYTHON_INCLUDE]) +  ]) +fi + # Option to<br>> > only build the consumer daemon and its libraries <br>> > AC_ARG_WITH([consumerd-only], AS_HELP_STRING([--with-consumerd-only],[Only<br>> > build the consumer daemon [default=no]]), @@ -214,6 +248,7 @@<br>> > AC_CONFIG_FILES([ src/bin/lttng-sessiond/Makefile <br>> > src/bin/lttng-relayd/Makefile src/bin/lttng/Makefile +  src/python/Makefile <br>> > tests/Makefile tests/kernel/Makefile tests/tools/Makefile @@ -260,6 +295,14<br>> > @@ AS_IF([test "x$lttng_ust_support" = "xyes"],[ AS_ECHO("Disabled") ])<br>> > <br>> > +#Python binding enabled/disabled +AS_ECHO_N("Python binding: ") <br>> > +AS_IF([test "x${enable_python:-yes}" = xyes], [ + AS_ECHO("Enabled") +],[ <br>> > + AS_ECHO("Disabled") +]) + # Do we build only the consumerd, or<br>> > everything AS_IF([test "x$consumerd_only" = "xyes"],[ AS_ECHO("Only the<br>> > consumerd daemon will be built.") diff --git a/src/Makefile.am<br>> > b/src/Makefile.am index 103337c..a65a5c1 100644 --- a/src/Makefile.am +++<br>> > b/src/Makefile.am @@ -1 +1,5 @@ SUBDIRS = common lib bin + +if USE_PYTHON <br>> > +SUBDIRS += python +endif diff --git a/src/python/Makefile.am<br>> > b/src/python/Makefile.am new file mode 100644 index 0000000..b67d550 ---<br>> > /dev/null +++ b/src/python/Makefile.am @@ -0,0 +1,25 @@ +lttng.i:<br>> > lttng.i.in +        sed "s/LTTNG_VERSION_STR/LTTng $(PACKAGE_VERSION)/g"<br>> > <lttng.i.in >lttng.i + +AM_CFLAGS = -I$(PYTHONINC) -I../lib/lttng-ctl<br>> > -I../common \ +              $(BUDDY_CFLAGS) + +EXTRA_DIST = lttng.i <br>> > +python_PYTHON = lttng.py +pyexec_LTLIBRARIES = _lttng.la + <br>> > +MAINTAINERCLEANFILES = lttng_wrap.c lttng.py + +_lttng_la_SOURCES =<br>> > lttng_wrap.c + +_lttng_la_LDFLAGS = -module + +_lttng_la_LIBADD =<br>> > ../lib/lttng-ctl/liblttng-ctl.la                 \ +<br>> > ../common/sessiond-comm/libsessiond-comm.la + +lttng_wrap.c: lttng.i +<br>> > $(SWIG) -python -I. -I$(top_srcdir)/src/common/sessiond-comm lttng.i + sed<br>> > -i "s/Python.h/python$(PYTHON_VERSION)\/Python.h/g" lttng_wrap.c +     sed -i<br>> > "s/PyObject \*m, \*d, \*md;/PyObject \*m, \*d;\n#if<br>> > defined(SWIGPYTHON_BUILTIN)\nPyObject *md;\n#endif/g" lttng_wrap.c + sed -i<br>> > "s/md = d/d/g" lttng_wrap.c +       sed -i<br>> > "s/(void)public_symbol;/(void)public_symbol;\n  md = d;/g" lttng_wrap.c <br>> > diff --git a/src/python/lttng.i.in b/src/python/lttng.i.in new file mode<br>> > 100644 index 0000000..4f3cfeb --- /dev/null +++ b/src/python/lttng.i.in @@<br>> > -0,0 +1,1023 @@ +%define DOCSTRING +"LTTNG_VERSION_STR + +The  LTTng<br>> > project  aims at providing highly efficient tracing tools for Linux. +It's<br>> > tracers help tracking down performance issues and debugging problems<br>> > involving +multiple concurrent processes and threads. Tracing across<br>> > multiple systems is also possible." +%enddef + <br>> > +%module(docstring=DOCSTRING) lttng + +%include "typemaps.i" +%include<br>> > "pyabc.i" +%{ +#define SWIG_FILE_WITH_INIT +#include <lttng/lttng.h> +%} + <br>> > +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned<br>> > long long uint64_t; +typedef long pid_t; + + +//<br>> > ============================================= +//                ENUMS +//<br>> > ============================================= + +%rename("DOMAIN_KERNEL")<br>> > LTTNG_DOMAIN_KERNEL; +%rename("DOMAIN_UST") LTTNG_DOMAIN_UST; +enum<br>> > lttng_domain_type { +      LTTNG_DOMAIN_KERNEL                   = 1, +<br>> > LTTNG_DOMAIN_UST                      = 2, +}; + +%rename("EVENT_ALL")<br>> > LTTNG_EVENT_ALL; +%rename("EVENT_TRACEPOINT") LTTNG_EVENT_TRACEPOINT; <br>> > +%rename("EVENT_PROBE") LTTNG_EVENT_PROBE; <br>> > +%rename("EVENT_FUNCTION")LTTNG_EVENT_FUNCTION; <br>> > +%rename("EVENT_FUNCTION_ENTRY") LTTNG_EVENT_FUNCTION_ENTRY; <br>> > +%rename("EVENT_NOOP") LTTNG_EVENT_NOOP; +%rename("EVENT_SYSCALL")<br>> > LTTNG_EVENT_SYSCALL; +enum lttng_event_type { +     LTTNG_EVENT_ALL<br>> > = -1, +      LTTNG_EVENT_TRACEPOINT                = 0, +    LTTNG_EVENT_PROBE<br>> > = 1, +     LTTNG_EVENT_FUNCTION                  = 2, +<br>> > LTTNG_EVENT_FUNCTION_ENTRY            = 3, +    LTTNG_EVENT_NOOP<br>> > = 4, +      LTTNG_EVENT_SYSCALL                   = 5, +}; + <br>> > +%rename("EVENT_LOGLEVEL_ALL") LTTNG_EVENT_LOGLEVEL_ALL; <br>> > +%rename("EVENT_LOGLEVEL_RANGE") LTTNG_EVENT_LOGLEVEL_RANGE; <br>> > +%rename("EVENT_LOGLEVEL_SINGLE") LTTNG_EVENT_LOGLEVEL_SINGLE; +enum<br>> > lttng_loglevel_type { +        LTTNG_EVENT_LOGLEVEL_ALL              = 0, +<br>> > LTTNG_EVENT_LOGLEVEL_RANGE            = 1, +    LTTNG_EVENT_LOGLEVEL_SINGLE<br>> > = 2, +}; + +%rename("LOGLEVEL_EMERG") LTTNG_LOGLEVEL_EMERG; <br>> > +%rename("LOGLEVEL_ALERT") LTTNG_LOGLEVEL_ALERT; +%rename("LOGLEVEL_CRIT")<br>> > LTTNG_LOGLEVEL_CRIT; +%rename("LOGLEVEL_ERR") LTTNG_LOGLEVEL_ERR; <br>> > +%rename("LOGLEVEL_WARNING") LTTNG_LOGLEVEL_WARNING; <br>> > +%rename("LOGLEVEL_NOTICE") LTTNG_LOGLEVEL_NOTICE; <br>> > +%rename("LOGLEVEL_INFO") LTTNG_LOGLEVEL_INFO; <br>> > +%rename("LOGLEVEL_DEBUG_SYSTEM") LTTNG_LOGLEVEL_DEBUG_SYSTEM; <br>> > +%rename("LOGLEVEL_DEBUG_PROGRAM") LTTNG_LOGLEVEL_DEBUG_PROGRAM; <br>> > +%rename("LOGLEVEL_DEBUG_PROCESS") LTTNG_LOGLEVEL_DEBUG_PROCESS; <br>> > +%rename("LOGLEVEL_DEBUG_MODULE") LTTNG_LOGLEVEL_DEBUG_MODULE; <br>> > +%rename("LOGLEVEL_DEBUG_UNIT") LTTNG_LOGLEVEL_DEBUG_UNIT; <br>> > +%rename("LOGLEVEL_DEBUG_FUNCTION") LTTNG_LOGLEVEL_DEBUG_FUNCTION; <br>> > +%rename("LOGLEVEL_DEBUG_LINE") LTTNG_LOGLEVEL_DEBUG_LINE; <br>> > +%rename("LOGLEVEL_DEBUG") LTTNG_LOGLEVEL_DEBUG; +enum lttng_loglevel { +<br>> > LTTNG_LOGLEVEL_EMERG                  = 0, +        LTTNG_LOGLEVEL_ALERT<br>> > = 1, +        LTTNG_LOGLEVEL_CRIT                   = 2, +<br>> > LTTNG_LOGLEVEL_ERR                    = 3, +        LTTNG_LOGLEVEL_WARNING<br>> > = 4, +        LTTNG_LOGLEVEL_NOTICE                 = 5, +<br>> > LTTNG_LOGLEVEL_INFO                   = 6, +<br>> > LTTNG_LOGLEVEL_DEBUG_SYSTEM           = 7, +<br>> > LTTNG_LOGLEVEL_DEBUG_PROGRAM          = 8, +<br>> > LTTNG_LOGLEVEL_DEBUG_PROCESS          = 9, +<br>> > LTTNG_LOGLEVEL_DEBUG_MODULE           = 10, +<br>> > LTTNG_LOGLEVEL_DEBUG_UNIT             = 11, +<br>> > LTTNG_LOGLEVEL_DEBUG_FUNCTION         = 12, +<br>> > LTTNG_LOGLEVEL_DEBUG_LINE             = 13, +        LTTNG_LOGLEVEL_DEBUG<br>> > = 14, +}; + +%rename("EVENT_SPLICE") LTTNG_EVENT_SPLICE; <br>> > +%rename("EVENT_MMAP") LTTNG_EVENT_MMAP; +enum lttng_event_output { +<br>> > LTTNG_EVENT_SPLICE                    = 0, +      LTTNG_EVENT_MMAP<br>> > = 1, +}; + +%rename("EVENT_CONTEXT_PID") LTTNG_EVENT_CONTEXT_PID; <br>> > +%rename("EVENT_CONTEXT_PERF_COUNTER") LTTNG_EVENT_CONTEXT_PERF_COUNTER; <br>> > +%rename("EVENT_CONTEXT_PROCNAME") LTTNG_EVENT_CONTEXT_PROCNAME; <br>> > +%rename("EVENT_CONTEXT_PRIO") LTTNG_EVENT_CONTEXT_PRIO; <br>> > +%rename("EVENT_CONTEXT_NICE") LTTNG_EVENT_CONTEXT_NICE; <br>> > +%rename("EVENT_CONTEXT_VPID") LTTNG_EVENT_CONTEXT_VPID; <br>> > +%rename("EVENT_CONTEXT_TID") LTTNG_EVENT_CONTEXT_TID; <br>> > +%rename("EVENT_CONTEXT_VTID") LTTNG_EVENT_CONTEXT_VTID; <br>> > +%rename("EVENT_CONTEXT_PPID") LTTNG_EVENT_CONTEXT_PPID; <br>> > +%rename("EVENT_CONTEXT_VPPID") LTTNG_EVENT_CONTEXT_VPPID; <br>> > +%rename("EVENT_CONTEXT_PTHREAD_ID") LTTNG_EVENT_CONTEXT_PTHREAD_ID; +enum<br>> > lttng_event_context_type { + LTTNG_EVENT_CONTEXT_PID               = 0, +<br>> > LTTNG_EVENT_CONTEXT_PERF_COUNTER      = 1, +    LTTNG_EVENT_CONTEXT_PROCNAME<br>> > = 2, +  LTTNG_EVENT_CONTEXT_PRIO              = 3, +<br>> > LTTNG_EVENT_CONTEXT_NICE              = 4, +    LTTNG_EVENT_CONTEXT_VPID<br>> > = 5, +      LTTNG_EVENT_CONTEXT_TID               = 6, +<br>> > LTTNG_EVENT_CONTEXT_VTID              = 7, +    LTTNG_EVENT_CONTEXT_PPID<br>> > = 8, +      LTTNG_EVENT_CONTEXT_VPPID             = 9, +<br>> > LTTNG_EVENT_CONTEXT_PTHREAD_ID        = 10, +}; + <br>> > +%rename("CALIBRATE_FUNCTION") LTTNG_CALIBRATE_FUNCTION; +enum<br>> > lttng_calibrate_type { +      LTTNG_CALIBRATE_FUNCTION              = 0, +}; + <br>> > + + +// ============================================= +//          TYPEMAPS +//<br>> > ============================================= + +//list_sessions <br>> > +%typemap(argout) struct lttng_session **sessions{ + +     int l =<br>> > PyInt_AsSsize_t($result); +  if (l >= 0) +        { +             PyObject *sessions =<br>> > PyList_New(0); +                int i; +                for(i=0; i<l; i++) +         { +                     PyObject *tmp =<br>> > PyTuple_New(4); +                    PyObject *name = PyString_FromString((*$1)[i].name); +<br>> > PyObject *path = PyString_FromString((*$1)[i].path); +                        PyObject *enabled<br>> > = PyInt_FromSize_t((*$1)[i].enabled); +                    PyObject *padding =<br>> > PyString_FromString((*$1)[i].padding); + +                       PyTuple_SetItem(tmp, 0,<br>> > name); +                     PyTuple_SetItem(tmp, 1, path); +                        PyTuple_SetItem(tmp, 2,<br>> > enabled); +                  PyTuple_SetItem(tmp, 3, padding); +                     PyList_Append(sessions,<br>> > tmp); +              } +             $result = sessions; +   } +} +%typemap(in,numinputs=0) struct<br>> > lttng_session **sessions (struct lttng_session *temp){ +       $1=&temp; +} + <br>> > +//list_domains +%typemap(argout) struct lttng_domain **domains{ + +     int l<br>> > = PyInt_AsSsize_t($result); +  if (l >= 0) +        { +             PyObject *dom =<br>> > PyList_New(0); +             int i; +                for(i=0; i<l; i++) +         { +                     PyObject *tmp =<br>> > PyTuple_New(5); +                    PyObject *type = PyInt_FromSize_t((*$1)[i].type); +<br>> > PyObject *execname = PyString_FromString((*$1)[i].attr.exec_name); +<br>> > PyObject *pid = PyInt_FromSize_t((*$1)[i].attr.pid); +                   PyObject *padding<br>> > = PyString_FromString((*$1)[i].padding); +                 PyObject *attrpadding =<br>> > PyString_FromString((*$1)[i].attr.padding); + +                      PyTuple_SetItem(tmp, 0,<br>> > type); +                     PyTuple_SetItem(tmp, 1, padding); +                     PyTuple_SetItem(tmp, 2,<br>> > pid); +                      PyTuple_SetItem(tmp, 3, execname); +                    PyTuple_SetItem(tmp, 4,<br>> > attrpadding); +                      PyList_Append(dom, tmp); +              } +             $result = dom; +        } +} <br>> > +%typemap(in,numinputs=0) struct lttng_domain **domains (struct<br>> > lttng_domain *temp){ +      $1=&temp; +} + +//list_channels +%typemap(argout)<br>> > struct lttng_channel **channels{ + +   int l = PyInt_AsSsize_t($result); +     if<br>> > (l >= 0) +     { +             PyObject *chan = PyList_New(0); +               int i; +                for(i=0; i<l;<br>> > i++) +              { +                     PyObject *tmp = PyTuple_New(4); +                       PyObject *name =<br>> > PyString_FromString((*$1)[i].name); +                       PyObject *enabled =<br>> > PyInt_FromSize_t((*$1)[i].enabled); +                    PyObject *padding =<br>> > PyString_FromString((*$1)[i].padding); + +                       PyObject *attrtmp =<br>> > PyTuple_New(7); +                        PyObject *overwrite =<br>> > PyInt_FromLong((*$1)[i].attr.overwrite); +                     PyObject *subbuf =<br>> > PyInt_FromSize_t((*$1)[i].attr.subbuf_size); +                    PyObject *num =<br>> > PyInt_FromSize_t((*$1)[i].attr.num_subbuf); +                        PyObject *switchtimer =<br>> > PyInt_FromSize_t((*$1)[i].attr.switch_timer_interval); +                     PyObject<br>> > *readtimer = PyInt_FromSize_t((*$1)[i].attr.read_timer_interval); +<br>> > PyObject *output = PyInt_FromSize_t((*$1)[i].attr.output); +                 PyObject<br>> > *attrpad = PyString_FromString((*$1)[i].attr.padding); + +<br>> > PyTuple_SetItem(attrtmp, 0, overwrite); +                     PyTuple_SetItem(attrtmp, 1,<br>> > subbuf); +                       PyTuple_SetItem(attrtmp, 2, num); +                     PyTuple_SetItem(attrtmp,<br>> > 3, switchtimer); +                  PyTuple_SetItem(attrtmp, 4, readtimer); +<br>> > PyTuple_SetItem(attrtmp, 5, output); +                     PyTuple_SetItem(attrtmp, 6,<br>> > attrpad); + +                    PyTuple_SetItem(tmp, 0, name); +                        PyTuple_SetItem(tmp, 1,<br>> > enabled); +                  PyTuple_SetItem(tmp, 2, padding); +                     PyTuple_SetItem(tmp, 3,<br>> > attrtmp); +                  PyList_Append(chan, tmp); +             } +             $result = chan; +       } +} <br>> > +%typemap(in,numinputs=0) struct lttng_channel **channels (struct<br>> > lttng_channel *temp){ +   $1=&temp; +} + +//list_events & list_tracepoints <br>> > +%typemap(argout) struct lttng_event **events{ + + int l =<br>> > PyInt_AsSsize_t($result); +  if (l >= 0) +        { +             PyObject *events =<br>> > PyList_New(0); +          int i; +                for(i=0; i<l; i++) +         { +                     PyObject *tmp =<br>> > PyTuple_New(10); +                   PyObject *name = PyString_FromString((*$1)[i].name); +<br>> > PyObject *type = PyInt_FromSize_t((*$1)[i].type); +                   PyObject<br>> > *logleveltype = PyInt_FromSize_t((*$1)[i].loglevel_type); +                 PyObject<br>> > *loglevel = PyInt_FromLong((*$1)[i].loglevel); +                    PyObject *enabled =<br>> > PyInt_FromLong((*$1)[i].enabled); +                      PyObject *pid =<br>> > PyInt_FromSize_t((*$1)[i].pid); +                    PyObject *padding =<br>> > PyString_FromString((*$1)[i].padding); +                 PyObject *attrpadding =<br>> > PyString_FromString((*$1)[i].attr.padding); + +                      PyObject *probe =<br>> > PyTuple_New(4); +                  PyObject *addr =<br>> > PyInt_FromSize_t((*$1)[i].attr.probe.addr); +                       PyObject *offset =<br>> > PyInt_FromSize_t((*$1)[i].attr.probe.offset); +                   PyObject *symbolname =<br>> > PyString_FromString((*$1)[i].attr.probe.symbol_name); +                       PyObject<br>> > *probepad = PyString_FromString((*$1)[i].attr.probe.padding); + +<br>> > PyObject *function = PyTuple_New(2); +                 PyObject *f_symbolname =<br>> > PyString_FromString((*$1)[i].attr.ftrace.symbol_name); +                    PyObject *f_pad<br>> > = PyString_FromString((*$1)[i].attr.ftrace.padding); + +<br>> > PyTuple_SetItem(function, 0, f_symbolname); +                    PyTuple_SetItem(function,<br>> > 1, f_pad); + +                     PyTuple_SetItem(probe, 0, addr); +<br>> > PyTuple_SetItem(probe, 1, offset); +                      PyTuple_SetItem(probe, 2,<br>> > symbolname); +                     PyTuple_SetItem(probe, 3, probepad); + +<br>> > PyTuple_SetItem(tmp, 0, name); +                    PyTuple_SetItem(tmp, 1, type); +<br>> > PyTuple_SetItem(tmp, 2, logleveltype); +                    PyTuple_SetItem(tmp, 3,<br>> > loglevel); +                 PyTuple_SetItem(tmp, 4, enabled); +                     PyTuple_SetItem(tmp,<br>> > 5, pid); +                      PyTuple_SetItem(tmp, 6, padding); +                     PyTuple_SetItem(tmp, 7,<br>> > probe); +                    PyTuple_SetItem(tmp, 8, function); +                    PyTuple_SetItem(tmp, 9,<br>> > attrpadding); +                      PyList_Append(events, tmp); +           } +             $result = events; +<br>> > } +} +%typemap(in,numinputs=0) struct lttng_event **events (struct<br>> > lttng_event *temp){ +      $1=&temp; +} + + + +//<br>> > ============================================= +//         FUNCTIONS +//<br>> > ============================================= + +%rename("create")<br>> > lttng_create_session(const char *name, const char *path); <br>> > +%rename("destroy") lttng_destroy_session(const char *name); <br>> > +%rename("_lttng_create_handle") lttng_create_handle(const char<br>> > *session_name, struct lttng_domain *domain); <br>> > +%rename("_lttng_destroy_handle") lttng_destroy_handle(struct lttng_handle<br>> > *handle); +%rename("_lttng_list_sessions") lttng_list_sessions(struct<br>> > lttng_session **sessions); +%rename("_lttng_list_domains")<br>> > lttng_list_domains(const char *session_name, struct lttng_domain<br>> > **domains); +%rename("_lttng_list_channels") lttng_list_channels(struct<br>> > lttng_handle *handle,struct lttng_channel **channels); <br>> > +%rename("_lttng_list_events") lttng_list_events(struct lttng_handle<br>> > *handle, const char *channel_name, struct lttng_event **events); <br>> > +%rename("_lttng_list_tracepoints") lttng_list_tracepoints(struct<br>> > lttng_handle *handle, struct lttng_event **events); <br>> > +%rename("session_daemon_alive") lttng_session_daemon_alive(void); <br>> > +%rename("set_tracing_group") lttng_set_tracing_group(const char *name); <br>> > +%rename("strerror") lttng_strerror(int code); <br>> > +%rename("_lttng_register_consumer") lttng_register_consumer(struct<br>> > lttng_handle *handle, const char *socket_path); +%rename("start")<br>> > lttng_start_tracing(const char *session_name); +%rename("stop")<br>> > lttng_stop_tracing(const char *session_name); <br>> > +%rename("_lttng_add_context") lttng_add_context(struct lttng_handle<br>> > *handle, struct lttng_event_context *ctx, const char *event_name, const<br>> > char *channel_name); +%rename("_lttng_enable_event")<br>> > lttng_enable_event(struct lttng_handle *handle, struct lttng_event *ev,<br>> > const char *channel_name); +%rename("_lttng_enable_channel")<br>> > lttng_enable_channel(struct lttng_handle *handle, struct lttng_channel<br>> > *chan); +%rename("_lttng_disable_event") lttng_disable_event(struct<br>> > lttng_handle *handle, const char *name, const char *channel_name); <br>> > +%rename("_lttng_disable_channel") lttng_disable_channel(struct<br>> > lttng_handle *handle, const char *name); +%rename("_lttng_calibrate")<br>> > lttng_calibrate(struct lttng_handle *handle, struct lttng_calibrate<br>> > *calibrate); +%rename("channel_set_default_attr")<br>> > lttng_channel_set_default_attr(struct lttng_domain *domain, struct<br>> > lttng_channel_attr *attr); + +//Redefined functions +struct lttng_handle<br>> > *lttng_create_handle(const char *session_name, +         struct lttng_domain<br>> > *domain); +void lttng_destroy_handle(struct lttng_handle *handle); +int<br>> > lttng_list_channels(struct lttng_handle *handle,struct lttng_channel<br>> > **channels); +int lttng_list_events(struct lttng_handle *handle, +            const<br>> > char *channel_name, struct lttng_event **events); +int<br>> > lttng_list_tracepoints(struct lttng_handle *handle, struct lttng_event<br>> > **events); +int lttng_add_context(struct lttng_handle *handle, struct<br>> > lttng_event_context *ctx, +               const char *event_name, const char<br>> > *channel_name); +int lttng_enable_event(struct lttng_handle *handle, +<br>> > struct lttng_event *ev, const char *channel_name); +int<br>> > lttng_enable_channel(struct lttng_handle *handle, struct lttng_channel<br>> > *chan); +int lttng_disable_event(struct lttng_handle *handle, +            const char<br>> > *name, const char *channel_name); +int lttng_disable_channel(struct<br>> > lttng_handle *handle, const char *name); +int lttng_calibrate(struct<br>> > lttng_handle *handle, struct lttng_calibrate *calibrate); +int<br>> > lttng_register_consumer(struct lttng_handle *handle, const char<br>> > *socket_path); +int lttng_list_sessions(struct lttng_session **sessions); <br>> > +int lttng_list_domains(const char *session_name, struct lttng_domain<br>> > **domains); + +//Functions not needing redefinition <br>> > +%feature("docstring")"create(str name, str path) -> int + +Create a new<br>> > tracing session using name and path. +Returns size of returned session<br>> > payload data or a negative error code." +int lttng_create_session(const<br>> > char *name, const char *path); + + +%feature("docstring")"destroy(str name)<br>> > -> int + +Tear down tracing session using name. +Returns size of returned<br>> > session payload data or a negative error code." +int<br>> > lttng_destroy_session(const char *name); + + <br>> > +%feature("docstring")"session_daemon_alive() -> int + +Check if session<br>> > daemon is alive. +Return 1 if alive or 0 if not. +On error returns a<br>> > negative value." +int lttng_session_daemon_alive(void); + + <br>> > +%feature("docstring")"set_tracing_group(str name) -> int + +Sets the<br>> > tracing_group variable with name. +This function allocates memory pointed<br>> > to by tracing_group. +On success, returns 0, on error, returns -1 (null<br>> > name) or -ENOMEM." +int lttng_set_tracing_group(const char *name); + + <br>> > +%feature("docstring")"strerror(int code) -> char + +Returns a human<br>> > readable string describing +the error code (a negative value)." +const char<br>> > *lttng_strerror(int code); + + +%feature("docstring")"start(str<br>> > session_name) -> int + +Start tracing for all traces of the session. <br>> > +Returns size of returned session payload data or a negative error code." <br>> > +int lttng_start_tracing(const char *session_name); + + <br>> > +%feature("docstring")"stop(str session_name) -> int + +Stop tracing for<br>> > all traces of the session. +Returns size of returned session payload data<br>> > or a negative error code." +int lttng_stop_tracing(const char<br>> > *session_name); + + +%feature("docstring")"channel_set_default_attr(Domain<br>> > domain, ChannelAttr attr) + +Set default channel attributes. +If either or<br>> > both of the arguments are null, attr content is zeroe'd." +void<br>> > lttng_channel_set_default_attr(struct lttng_domain *domain, struct<br>> > lttng_channel_attr *attr); + + +//<br>> > ============================================= +// Python redefinition of<br>> > some functions +//    (List and Handle-related) +//<br>> > ============================================= + +%feature("docstring")"" <br>> > +%pythoncode %{ + +def list_sessions(): +     """ +    list_sessions() -> dict + +<br>> > Ask the session daemon for all available sessions. +  Returns a dict of<br>> > Session instances, the key is the name; +  on error, returns a negative<br>> > value. +        """ + +  ses_list = _lttng_list_sessions() +     if type(ses_list) is<br>> > int: +          return ses_list + +     sessions = {} + +       for ses_elements in<br>> > ses_list: +              ses = Session() +               ses.name = ses_elements[0] +            ses.path =<br>> > ses_elements[1] +         ses.enabled = ses_elements[2] +         ses.padding =<br>> > ses_elements[3] + +            sessions[ses.name] = ses + +    return sessions + + +def<br>> > list_domains(session_name): +       """ +    list_domains(str session_name) -> list <br>> > + +       Ask the session daemon for all available domains of a session. +<br>> > Returns a list of Domain instances; +       on error, returns a negative value. +<br>> > """ + + dom_list = _lttng_list_domains(session_name) +  if type(dom_list) is<br>> > int: +          return dom_list + +     domains = [] + +        for dom_elements in dom_list: <br>> > +             dom = Domain() +                dom.type = dom_elements[0] +            dom.paddinf =<br>> > dom_elements[1] +              dom.attr.pid = dom_elements[2] +                dom.attr.exec_name =<br>> > dom_elements[3] +               dom.attr.padding = dom_elements[4] + +<br>> > domains.append(dom) + +       return domains + + +def list_channels(handle): +<br>> > """ +        list_channels(Handle handle) -> dict + +     Ask the session daemon for<br>> > all available channels of a session. +    Returns a dict of Channel instances,<br>> > the key is the name; +  on error, returns a negative value. +   """ + +  try: +<br>> > chan_list = _lttng_list_channels(handle._h) + except AttributeError: +<br>> > raise TypeError("in method 'list_channels', argument 1 must be a Handle<br>> > instance") + + if type(chan_list) is int: +            return chan_list + +    channels<br>> > = {} + +    for channel_elements in chan_list: +            chan = Channel() +<br>> > chan.name = channel_elements[0] +         chan.enabled = channel_elements[1] +<br>> > chan.padding = channel_elements[2] +            chan.attr.overwrite =<br>> > channel_elements[3][0] +               chan.attr.subbuf_size = channel_elements[3][1] +<br>> > chan.attr.num_subbuf = channel_elements[3][2] +<br>> > chan.attr.switch_timer_interval = channel_elements[3][3] +<br>> > chan.attr.read_timer_interval = channel_elements[3][4] +           chan.attr.output<br>> > = channel_elements[3][5] +          chan.attr.padding = channel_elements[3][6] + +<br>> > channels[chan.name] = chan + +        return channels + + +def list_events(handle,<br>> > channel_name): +        """ +    list_events(Handle handle, str channel_name) -><br>> > dict + +  Ask the session daemon for all available events of a session<br>> > channel. +      Returns a dict of Event instances, the key is the name; +       on<br>> > error, returns a negative value. +        """ + +  try: +          ev_list =<br>> > _lttng_list_events(handle._h, channel_name) +      except AttributeError: +<br>> > raise TypeError("in method 'list_events', argument 1 must be a Handle<br>> > instance") + +   if type(ev_list) is int: +              return ev_list + +      events = {} <br>> > + +     for ev_elements in ev_list: +           ev = Event() +          ev.name =<br>> > ev_elements[0] +           ev.type = ev_elements[1] +              ev.loglevel_type =<br>> > ev_elements[2] +          ev.loglevel = ev_elements[3] +          ev.enabled =<br>> > ev_elements[4] +                ev.pid = ev_elements[5] +               ev.attr.padding =<br>> > ev_elements[6] +           ev.attr.probe.addr = ev_elements[7][0] +<br>> > ev.attr.probe.offset = ev_elements[7][1] +          ev.attr.probe.symbol_name =<br>> > ev_elements[7][2] +              ev.attr.probe.padding = ev_elements[7][3] +<br>> > ev.attr.ftrace.symbol_name = ev_elements[8][0] +         ev.attr.ftrace.padding =<br>> > ev_elements[8][1] +         ev.attr.padding = ev_elements[9] + +            events[ev.name]<br>> > = ev + +     return events + + +def list_tracepoints(handle): +      """ +<br>> > list_tracepoints(Handle handle) -> dict + +  Returns a dict of Event<br>> > instances, the key is the name; +    on error, returns a negative value. +<br>> > """ + + try: +          ev_list = _lttng_list_tracepoints(handle._h) +  except<br>> > AttributeError: +             raise TypeError("in method 'list_tracepoints', argument<br>> > 1 must be a Handle instance") + +  if type(ev_list) is int: +              return<br>> > ev_list + +   events = {} + + for ev_elements in ev_list: +           ev = Event() +<br>> > ev.name = ev_elements[0] +            ev.type = ev_elements[1] +              ev.loglevel_type =<br>> > ev_elements[2] +          ev.loglevel = ev_elements[3] +          ev.enabled =<br>> > ev_elements[4] +                ev.pid = ev_elements[5] +               ev.attr.padding =<br>> > ev_elements[6] +           ev.attr.probe.addr = ev_elements[7][0] +<br>> > ev.attr.probe.offset = ev_elements[7][1] +          ev.attr.probe.symbol_name =<br>> > ev_elements[7][2] +              ev.attr.probe.padding = ev_elements[7][3] +<br>> > ev.attr.ftrace.symbol_name = ev_elements[8][0] +         ev.attr.ftrace.padding =<br>> > ev_elements[8][1] +         ev.attr.padding = ev_elements[9] + +            events[ev.name]<br>> > = ev + +     return events + + +def register_consumer(handle, socket_path): +<br>> > """ +        register_consumer(Handle handle, str socket_path) -> int + + Register<br>> > an outside consumer. +      Returns size of returned session payload data or a<br>> > negative error code. +    """ + +  try: +          return<br>> > _lttng_register_consumer(handle._h, socket_path) +    except AttributeError: +<br>> > raise TypeError("in method 'register_consumer', argument 1 must be a Handle<br>> > instance") + + +def add_context(handle, event_context, event_name,<br>> > channel_name): +     """ +    add_context(Handle handle, EventContext ctx, +<br>> > str event_name, str channel_name) -> int + +       Add context to event and/or<br>> > channel. +       If event_name is None, the context is applied to all events of<br>> > the channel. +        If channel_name is None, a lookup of the event's channel is<br>> > done. +  If both are None, the context is applied to all events of all<br>> > channels. +    Returns the size of the returned payload data or a negative<br>> > error code. +    """ + +  try: +          return _lttng_add_context(handle._h,<br>> > event_context, event_name, channel_name) +      except AttributeError: +                raise<br>> > TypeError("in method 'add_context', argument 1 must be a Handle instance") <br>> > + + +def enable_event(handle, event, channel_name): + """ +<br>> > enable_event(Handle handle, Event event, +                  str channel_name) -> int + <br>> > + Enable event(s) for a channel. +        If no event name is specified, all<br>> > events are enabled. +     If no channel name is specified, the default<br>> > 'channel0' is used. +   Returns size of returned session payload data or a<br>> > negative error code. +    """ + +  try: +          return<br>> > _lttng_enable_event(handle._h, event, channel_name) + except<br>> > AttributeError: +             raise TypeError("in method 'enable_event', argument 1<br>> > must be a Handle instance") + + +def enable_channel(handle, channel): +<br>> > """ +      enable_channel(Handle handle, Channel channel -> int + +     Enable<br>> > channel per domain +  Returns size of returned session payload data or a<br>> > negative error code. +    """ + +  try: +          return<br>> > _lttng_enable_channel(handle._h, channel) +   except AttributeError: +                raise<br>> > TypeError("in method 'enable_channel', argument 1 must be a Handle<br>> > instance") + + +def disable_event(handle, name, channel_name): +       """ +<br>> > disable_event(Handle handle, str name, str channel_name) -> int + +  Disable<br>> > event(s) of a channel and domain. +  If no event name is specified, all<br>> > events are disabled. +    If no channel name is specified, the default<br>> > 'channel0' is used. +   Returns size of returned session payload data or a<br>> > negative error code +     """ + +  try: +          return<br>> > _lttng_disable_event(handle._h, name, channel_name) + except<br>> > AttributeError: +             raise TypeError("in method 'disable_event', argument 1<br>> > must be a Handle instance") + + +def disable_channel(handle, name): +       """ +<br>> > disable_channel(Handle handle, str name) -> int + +  All tracing will be<br>> > stopped for registered events of the channel. +  Returns size of returned<br>> > session payload data or a negative error code. +    """ + +  try: +          return<br>> > _lttng_disable_channel(handle._h, name) +     except AttributeError: +                raise<br>> > TypeError("in method 'disable_channel', argument 1 must be a Handle<br>> > instance") + + +def calibrate(handle, calibrate): +   """ +    calibrate(Handle<br>> > handle, Calibrate calibrate) -> int + +  Quantify LTTng overhead. +      Returns<br>> > size of returned session payload data or a negative error code. +    """ + +<br>> > try: +                return _lttng_calibrate(handle._h, calibrate) + except<br>> > AttributeError: +             raise TypeError("in method 'calibrate', argument 1 must<br>> > be a Handle instance") +%} + + +//<br>> > ============================================= +//            Handle class +//   Used<br>> > to prevent freeing unallocated memory +//<br>> > ============================================= + +%feature("docstring")"" <br>> > +%feature("autodoc", "1"); + +%pythoncode %{ +class Handle: +        """ +<br>> > Manages a handle. +   Takes two arguments: (str session_name, Domain domain) <br>> > +    """ + +  __frozen = False + +    def __init__(self, session_name, domain): +<br>> > if type(session_name) is not str: +                      raise TypeError("in method<br>> > '__init__', argument 2 of type 'str'") +                if type(domain) is not Domain and<br>> > domain is not None: +                      raise TypeError("in method '__init__', argument 3<br>> > of type 'lttng.Domain'") + +             self._sname = session_name +            if domain is<br>> > None: +                 self._domtype = None +          else: +                 self._domtype = domain.type +<br>> > self._h = _lttng_create_handle(session_name, domain) +         self.__frozen =<br>> > True + +     def __del__(self): +            _lttng_destroy_handle(self._h) + +      def<br>> > __repr__(self): +                if self._domtype == 1: +                        domstr = "DOMAIN_KERNEL" +<br>> > elif self._domtype == 2: +                      domstr = "DOMAIN_UST" +               else: +                 domstr =<br>> > self._domtype + +           return "lttng.Handle; session('{}'),<br>> > domain.type({})".format( +                    self._sname, domstr) + +        def __setattr__(self,<br>> > attr, val): +          if self.__frozen: +                     raise NotImplementedError("cannot<br>> > modify attributes") +            else: +                 self.__dict__[attr] = val +%} + + +//<br>> > ============================================= +//              STRUCTURES +//<br>> > ============================================= + +%rename("Domain")<br>> > lttng_domain; +%rename("EventContext") lttng_event_context; <br>> > +%rename("Event") lttng_event; +%rename("Calibrate") lttng_calibrate; <br>> > +%rename("ChannelAttr") lttng_channel_attr; +%rename("Channel")<br>> > lttng_channel; +%rename("Session") lttng_session; + +struct lttng_domain{ +<br>> > enum lttng_domain_type type; +        char padding[LTTNG_DOMAIN_PADDING1]; + +<br>> > union { +           pid_t pid; +            char exec_name[NAME_MAX]; +             char<br>> > padding[LTTNG_DOMAIN_PADDING2]; +       } attr; + +     %extend { +             char<br>> > *__repr__() { +                 static char temp[256]; +                        switch ( $self->type ) { +<br>> > case 1: +                              sprintf(temp, "lttng.Domain; type(DOMAIN_KERNEL)"); +<br>> > break; +                     case 2: +                               sprintf(temp, "lttng.Domain; type(DOMAIN_UST)"); +<br>> > break; +                        default: +                              sprintf(temp, "lttng.Domain; type(%i)",<br>> > $self->type); +                         break; +                        } +                     return &temp[0]; +          } +     } +}; + +struct<br>> > lttng_event_context { +      enum lttng_event_context_type ctx; +    char<br>> > padding[LTTNG_EVENT_CONTEXT_PADDING1]; + +      union { +               struct<br>> > lttng_event_perf_counter_ctx perf_counter; +          char<br>> > padding[LTTNG_EVENT_CONTEXT_PADDING2]; +        } u; + +        %extend { +             char<br>> > *__repr__() { +                 static char temp[256]; +                        switch ( $self->ctx ) { +<br>> > case 0: +                               sprintf(temp, "lttng.EventContext; ctx(EVENT_CONTEXT_PID)"); +<br>> > break; +                    case 1: +                               sprintf(temp, "lttng.EventContext;<br>> > ctx(EVENT_CONTEXT_PERF_COUNTER)"); +                            break; +                        case 2: +<br>> > sprintf(temp, "lttng.EventContext; ctx(EVENT_CONTEXT_PROCNAME)"); +<br>> > break; +                  case 3: +                               sprintf(temp, "lttng.EventContext;<br>> > ctx(EVENT_CONTEXT_PRIO)"); +                            break; +                        case 4: +                               sprintf(temp,<br>> > "lttng.EventContext; ctx(EVENT_CONTEXT_NICE)"); +                            break; +                        case 5: +<br>> > sprintf(temp, "lttng.EventContext; ctx(EVENT_CONTEXT_VPID)"); +                          break; +<br>> > case 6: +                           sprintf(temp, "lttng.EventContext; ctx(EVENT_CONTEXT_TID)"); +<br>> > break; +                    case 7: +                               sprintf(temp, "lttng.EventContext;<br>> > ctx(EVENT_CONTEXT_VTID)"); +                            break; +                        case 8: +                               sprintf(temp,<br>> > "lttng.EventContext; ctx(EVENT_CONTEXT_PPID)"); +                            break; +                        case 9: +<br>> > sprintf(temp, "lttng.EventContext; ctx(EVENT_CONTEXT_VPPID)"); +                         break; <br>> > +                    case 10: +                              sprintf(temp, "lttng.EventContext;<br>> > ctx(EVENT_CONTEXT_PTHREAD_ID)"); +                              break; +                        default: +<br>> > sprintf(temp, "lttng.EventContext; type(%i)", $self->ctx); +                         break; +<br>> > } +                 return &temp[0]; +          } +     } +}; + +struct lttng_event_probe_attr { +<br>> > uint64_t addr; +  uint64_t offset; +      char<br>> > symbol_name[LTTNG_SYMBOL_NAME_LEN]; +   char<br>> > padding[LTTNG_EVENT_PROBE_PADDING1]; +}; + +struct<br>> > lttng_event_function_attr { +     char symbol_name[LTTNG_SYMBOL_NAME_LEN]; +<br>> > char padding[LTTNG_EVENT_FUNCTION_PADDING1]; +}; + +struct lttng_event { +<br>> > enum lttng_event_type type; +       char name[LTTNG_SYMBOL_NAME_LEN]; + +   enum<br>> > lttng_loglevel_type loglevel_type; +    int loglevel; + +       int32_t enabled; +<br>> > pid_t pid; + +    char padding[LTTNG_EVENT_PADDING1]; + + union { +               struct<br>> > lttng_event_probe_attr probe; +               struct lttng_event_function_attr ftrace; <br>> > + +                char padding[LTTNG_EVENT_PADDING2]; +   } attr; + +     %extend { +             char<br>> > *__repr__() { +                 static char temp[512]; +                        char evtype[50]; +                      char<br>> > logtype[50]; + +                        switch ( $self->type ) { +                   case -1: +<br>> > sprintf(evtype, "EVENT_ALL"); +                         break; +                        case 0: +                               sprintf(evtype,<br>> > "EVENT_TRACEPOINT"); +                             break; +                        case 1: +                               sprintf(evtype,<br>> > "EVENT_PROBE"); +                          break; +                        case 2: +                               sprintf(evtype,<br>> > "EVENT_FUNCTION"); +                               break; +                        case 3: +                               sprintf(evtype,<br>> > "EVENT_FUNCTION_ENTRY"); +                         break; +                        case 4: +                               sprintf(evtype,<br>> > "EVENT_NOOP"); +                           break; +                        case 5: +                               sprintf(evtype,<br>> > "EVENT_SYSCALL"); +                                break; +                        default: +                              sprintf(evtype, "%i",<br>> > $self->type); +                           break; +                        } + +                   switch ( $self->loglevel_type ) { +<br>> > case 0: +                             sprintf(logtype, "EVENT_LOGLEVEL_ALL"); +                             break; +                        case<br>> > 1: +                            sprintf(logtype, "EVENT_LOGLEVEL_RANGE"); +                           break; +                        case 2: +<br>> > sprintf(logtype, "EVENT_LOGLEVEL_SINGLE"); +                             break; +                        default: +<br>> > sprintf(logtype, "%i", $self->loglevel_type); +                              break; +                        } + +<br>> > sprintf(temp, "lttng.Event; name('%s'), type(%s), " +<br>> > "loglevel_type(%s), loglevel(%i), " +                             "enabled(%s), pid(%i)", +<br>> > $self->name, evtype, logtype, $self->loglevel, +                           $self->enabled ? "True"<br>> > : "False", $self->pid); +                  return &temp[0]; +          } +     } +}; + +struct<br>> > lttng_calibrate { +  enum lttng_calibrate_type type; +       char<br>> > padding[LTTNG_CALIBRATE_PADDING1]; + +  %extend { +             char *__repr__() { +<br>> > static char temp[256]; +                        switch ( $self->type ) { +                   case 0: +<br>> > sprintf(temp, "lttng.Calibrate; type(CALIBRATE_FUNCTION)"); +                            break; +<br>> > default: +                          sprintf(temp, "lttng.Calibrate; type(%i)", $self->type); +<br>> > break; +                     } +                     return &temp[0]; +          } +     } +}; + +struct lttng_channel_attr<br>> > { +       int overwrite; +        uint64_t subbuf_size; + uint64_t num_subbuf; +<br>> > unsigned int switch_timer_interval; + unsigned int read_timer_interval; +<br>> > enum lttng_event_output output; + +      char<br>> > padding[LTTNG_CHANNEL_ATTR_PADDING1]; + +       %extend { +             char *__repr__() { <br>> > +                        static char temp[256]; +                        char evout[25]; + +                     switch ( $self->output<br>> > ) { +                      case 0: +                               sprintf(evout, "EVENT_SPLICE"); +                             break; +                        case<br>> > 1: +                            sprintf(evout, "EVENT_MMAP"); +                               break; +                        default: +<br>> > sprintf(evout, "%i", $self->output); +                               break; +                        } +                     sprintf(temp,<br>> > "lttng.ChannelAttr; overwrite(%i), subbuf_size(%lu), " +<br>> > "num_subbuf(%lu), switch_timer_interval(%u), " +<br>> > "read_timer_interval(%u), output(%s)", +                         $self->overwrite,<br>> > $self->subbuf_size, $self->num_subbuf, +                          $self->switch_timer_interval,<br>> > $self->read_timer_interval, +                            evout); +                       return &temp[0]; +          } +     } +}; <br>> > + +struct lttng_channel { +   char name[LTTNG_SYMBOL_NAME_LEN]; +     uint32_t<br>> > enabled; +  struct lttng_channel_attr attr; +       char<br>> > padding[LTTNG_CHANNEL_PADDING1]; + +    %extend { +             char *__repr__() { +<br>> > static char temp[512]; +                        sprintf(temp, "lttng.Channel; name('%s'),<br>> > enabled(%s)", +                          $self->name, $self->enabled ? "True" : "False"); +<br>> > return &temp[0]; +          } +     } +}; + +struct lttng_session { +       char<br>> > name[NAME_MAX]; +       char path[PATH_MAX]; +  uint32_t enabled; +     char<br>> > padding[LTTNG_SESSION_PADDING1]; + +    %extend { +             char *__repr__() { +<br>> > static char temp[512]; +                        sprintf(temp, "lttng.Session; name('%s'),<br>> > path('%s'), enabled(%s)", +                              $self->name, $self->path, +<br>> > $self->enabled ? "True" : "False"); +                       return &temp[0]; +          } +     } +}; diff<br>> > --git a/src/python/tests/example.py b/src/python/tests/example.py new file<br>> > mode 100644 index 0000000..9703170 --- /dev/null +++<br>> > b/src/python/tests/example.py @@ -0,0 +1,109 @@ +#This example shows<br>> > basically how to use the lttng-tools python module + +from lttng import * <br>> > + +# This error will be raised is something goes wrong +class<br>> > LTTngError(Exception): +     def __init__(self, value): +            self.value = value +<br>> > def __str__(self): +            return repr(self.value) + +#Setting up the domain to<br>> > use +dom = Domain() +dom.type = DOMAIN_KERNEL + +#Setting up a channel to<br>> > use +channel = Channel() +channel.name = "mychan" +channel.attr.overwrite =<br>> > 0 +channel.attr.subbuf_size = 4096 +channel.attr.num_subbuf = 8 <br>> > +channel.attr.switch_timer_interval = 0 +channel.attr.read_timer_interval =<br>> > 200 +channel.attr.output = EVENT_SPLICE + +#Setting up some events that<br>> > will be used +event = Event() +event.type = EVENT_TRACEPOINT <br>> > +event.loglevel_type = EVENT_LOGLEVEL_ALL + +sched_switch = Event() <br>> > +sched_switch.name = "sched_switch" +sched_switch.type = EVENT_TRACEPOINT <br>> > +sched_switch.loglevel_type = EVENT_LOGLEVEL_ALL + +sched_process_exit =<br>> > Event() +sched_process_exit.name = "sched_process_exit" <br>> > +sched_process_exit.type = EVENT_TRACEPOINT <br>> > +sched_process_exit.loglevel_type = EVENT_LOGLEVEL_ALL + <br>> > +sched_process_free = Event() +sched_process_free.name =<br>> > "sched_process_free" +sched_process_free.type = EVENT_TRACEPOINT <br>> > +sched_process_free.loglevel_type = EVENT_LOGLEVEL_ALL + + +#Creating a new<br>> > session +res = create("test","/lttng-traces/test") +if res<0: +    raise<br>> > LTTngError(strerror(res)) + +#Creating handle +han = None +han =<br>> > Handle("test", dom) +if han is None: +   raise LTTngError("Handle not<br>> > created") + +#Enabling the kernel channel +res = enable_channel(han,<br>> > channel) +if res<0: +      raise LTTngError(strerror(res)) + +#Enabling some<br>> > events in given channel +#To enable all events in default channel, use <br>> > +#enable_event(han, event, None) +res = enable_event(han, sched_switch,<br>> > channel.name) +if res<0: +        raise LTTngError(strerror(res)) + +res =<br>> > enable_event(han, sched_process_exit, channel.name) +if res<0: + raise<br>> > LTTngError(strerror(res)) + +res = enable_event(han, sched_process_free,<br>> > channel.name) +if res<0: +      raise LTTngError(strerror(res)) + +#Disabling an<br>> > event +res = disable_event(han, sched_switch.name, channel.name) +if<br>> > res<0: + raise LTTngError(strerror(res)) + +#Getting a list of the<br>> > channels +l = list_channels(han) +if type(l) is int: +             raise<br>> > LTTngError(strerror(l)) + +#Starting the trace +res = start("test") +if<br>> > res<0: +       raise LTTngError(strerror(res)) + +#Stopping the trace +res =<br>> > stop("test") +if res<0: + raise LTTngError(strerror(res)) + +#Disabling a<br>> > channel +res = disable_channel(han, channel.name) +if res<0: +    raise<br>> > LTTngError(strerror(res)) + +#Destroying the handle +del han + +#Destroying<br>> > the session +res = destroy("test") +if res<0: +    raise<br>> > LTTngError(strerror(res)) diff --git a/src/python/tests/run.sh<br>> > b/src/python/tests/run.sh new file mode 100644 index 0000000..7de819b ---<br>> > /dev/null +++ b/src/python/tests/run.sh @@ -0,0 +1 @@ +python tests.py diff<br>> > --git a/src/python/tests/tests.py b/src/python/tests/tests.py new file mode<br>> > 100644 index 0000000..a4be981 --- /dev/null +++<br>> > b/src/python/tests/tests.py @@ -0,0 +1,310 @@ +import unittest +import os <br>> > +import time +from lttng import * + +class TestLttngPythonModule<br>> > (unittest.TestCase): + +     def test_kernel_all_events(self): +             dom =<br>> > Domain() +             dom.type = DOMAIN_KERNEL + +            event = Event() +               event.type =<br>> > EVENT_TRACEPOINT +              event.loglevel_type = EVENT_LOGLEVEL_ALL + +            han =<br>> > Handle("test_kernel_all_ev", dom) + +                r =<br>> > create("test_kernel_all_ev","/lttng-traces/test") +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +                r = enable_event(han,<br>> > event, None) +         self.assertGreaterEqual(r, 0, strerror(r)) + +          r =<br>> > start("test_kernel_all_ev") +          self.assertGreaterEqual(r, 0, strerror(r)) +<br>> > time.sleep(2) + +               r = stop("test_kernel_all_ev") +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +            r =<br>> > destroy("test_kernel_all_ev") +                self.assertGreaterEqual(r, 0,<br>> > strerror(r)) + + +     def test_kernel_event(self): + +                dom = Domain() +<br>> > dom.type = DOMAIN_KERNEL + +                channel = Channel() +           channel.name="mychan" <br>> > +           channel.attr.overwrite = 0 +            channel.attr.subbuf_size = 4096 +<br>> > channel.attr.num_subbuf = 8 +              channel.attr.switch_timer_interval = 0 +<br>> > channel.attr.read_timer_interval = 200 +            channel.attr.output =<br>> > EVENT_SPLICE + +               sched_switch = Event() +                sched_switch.name =<br>> > "sched_switch" +               sched_switch.type = EVENT_TRACEPOINT +<br>> > sched_switch.loglevel_type = EVENT_LOGLEVEL_ALL + +           sched_process_exit =<br>> > Event() +               sched_process_exit.name = "sched_process_exit" +<br>> > sched_process_exit.type = EVENT_TRACEPOINT +<br>> > sched_process_exit.loglevel_type = EVENT_LOGLEVEL_ALL + +<br>> > sched_process_free = Event() +               sched_process_free.name =<br>> > "sched_process_free" +           sched_process_free.type = EVENT_TRACEPOINT +<br>> > sched_process_free.loglevel_type = EVENT_LOGLEVEL_ALL + +               han =<br>> > Handle("test_kernel_event", dom) + +         #Create session test +          r =<br>> > create("test_kernel_event","/lttng-traces/test") +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +         #Enabling channel tests +<br>> > r = enable_channel(han, channel) +         self.assertGreaterEqual(r, 0,<br>> > strerror(r)) + +               #Enabling events tests +                r = enable_event(han,<br>> > sched_switch, channel.name) +          self.assertGreaterEqual(r, 0, strerror(r)) <br>> > + +              r = enable_event(han, sched_process_exit, channel.name) +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +             r = enable_event(han,<br>> > sched_process_free, channel.name) +            self.assertGreaterEqual(r, 0,<br>> > strerror(r)) + +               #Disabling events tests +               r = disable_event(han,<br>> > sched_switch.name, channel.name) +            self.assertGreaterEqual(r, 0,<br>> > strerror(r)) + +               r = disable_event(han, sched_process_free.name,<br>> > channel.name) +              self.assertGreaterEqual(r, 0, strerror(r)) + +          #Renabling<br>> > events tests +            r = enable_event(han, sched_switch, channel.name) +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +           r = enable_event(han,<br>> > sched_process_free, channel.name) +            self.assertGreaterEqual(r, 0,<br>> > strerror(r)) + +               #Start, stop, destroy +         r = start("test_kernel_event") +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) +              time.sleep(2) + +               r =<br>> > stop("test_kernel_event") +            self.assertGreaterEqual(r, 0, strerror(r)) + +<br>> > r=disable_channel(han, channel.name) +                self.assertGreaterEqual(r, 0,<br>> > strerror(r)) + +               r=destroy("test_kernel_event") +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + + + +        def<br>> > test_ust_all_events(self): +             dom = Domain() +                dom.type = DOMAIN_UST + +<br>> > event = Event() +          event.type = EVENT_TRACEPOINT +         event.loglevel_type =<br>> > EVENT_LOGLEVEL_ALL + +         han = Handle("test_ust_all_ev", dom) + +              r =<br>> > create("test_ust_all_ev","/lttng-traces/test") +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +           r = enable_event(han,<br>> > event, None) +         self.assertGreaterEqual(r, 0, strerror(r)) + +          r =<br>> > start("test_ust_all_ev") +             self.assertGreaterEqual(r, 0, strerror(r)) +<br>> > time.sleep(2) + +               r = stop("test_ust_all_ev") +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +               r =<br>> > destroy("test_ust_all_ev") +           self.assertGreaterEqual(r, 0, strerror(r)) + <br>> > + +    def test_ust_event(self): + +           dom = Domain() +                dom.type = DOMAIN_UST <br>> > + +           channel = Channel() +           channel.name="mychan" +               channel.attr.overwrite<br>> > = 0 +         channel.attr.subbuf_size = 4096 +               channel.attr.num_subbuf = 8 +<br>> > channel.attr.switch_timer_interval = 0 +               channel.attr.read_timer_interval<br>> > = 200 +             channel.attr.output = EVENT_MMAP + +            ev1 = Event() +         ev1.name =<br>> > "tp1" +         ev1.type = EVENT_TRACEPOINT +           ev1.loglevel_type =<br>> > EVENT_LOGLEVEL_ALL + +           ev2 = Event() +         ev2.name = "ev2" +            ev2.type =<br>> > EVENT_TRACEPOINT +                ev2.loglevel_type = EVENT_LOGLEVEL_ALL + +              ev3 =<br>> > Event() +              ev3.name = "ev3" +            ev3.type = EVENT_TRACEPOINT +<br>> > ev3.loglevel_type = EVENT_LOGLEVEL_ALL + +             han = Handle("test_ust_event",<br>> > dom) + +            #Create session test +          r =<br>> > create("test_ust_event","/lttng-traces/test") +              self.assertGreaterEqual(r,<br>> > 0, strerror(r)) + +               #Enabling channel tests +               r = enable_channel(han,<br>> > channel) +           self.assertGreaterEqual(r, 0, strerror(r)) + +          #Enabling<br>> > events tests +             r = enable_event(han, ev1, channel.name) +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +            r = enable_event(han, ev2,<br>> > channel.name) +           self.assertGreaterEqual(r, 0, strerror(r)) + +          r =<br>> > enable_event(han, ev3, channel.name) +           self.assertGreaterEqual(r, 0,<br>> > strerror(r)) + +               #Disabling events tests +               r = disable_event(han,<br>> > ev1.name, channel.name) +             self.assertGreaterEqual(r, 0, strerror(r)) + +<br>> > r = disable_event(han, ev3.name, channel.name) +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +            #Renabling events tests +<br>> > r = enable_event(han, ev1, channel.name) +         self.assertGreaterEqual(r, 0,<br>> > strerror(r)) + +               r = enable_event(han, ev3, channel.name) +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +            #Start, stop +          r =<br>> > start("test_ust_event") +              self.assertGreaterEqual(r, 0, strerror(r)) +<br>> > time.sleep(2) + +               r = stop("test_ust_event") +          self.assertGreaterEqual(r,<br>> > 0, strerror(r)) + +               #Restart/restop +               r = start("test_ust_event") +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) +         time.sleep(2) + +               r =<br>> > stop("test_ust_event") +               self.assertGreaterEqual(r, 0, strerror(r)) + +<br>> > #Disabling channel and destroy +              r=disable_channel(han, channel.name) +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +<br>> > r=destroy("test_ust_event") +             self.assertGreaterEqual(r, 0, strerror(r)) <br>> > + + +    def test_other_functions(self): +               dom = Domain() +<br>> > dom.type=DOMAIN_KERNEL + +          event=Event() +         event.type=EVENT_TRACEPOINT +<br>> > event.loglevel_type=EVENT_LOGLEVEL_ALL + +             calib = Calibrate() +<br>> > calib.type = CALIBRATE_FUNCTION + +            ctx = EventContext() +<br>> > ctx.type=EVENT_CONTEXT_PID + +                chattr = ChannelAttr() +                chattr.overwrite<br>> > = 0 +               chattr.subbuf_size = 4096 +             chattr.num_subbuf = 8 +<br>> > chattr.switch_timer_interval = 0 +           chattr.read_timer_interval = 200 +<br>> > chattr.output = EVENT_SPLICE + +          han = Handle("test_otherf" , dom) + +         r<br>> > = create("test_otherf","/lttng-traces/test") +         self.assertGreaterEqual(r,<br>> > 0, strerror(r)) + +               r = enable_event(han, event, None) +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +          #Calibrate test +               r =<br>> > calibrate(han , calib) +         self.assertGreaterEqual(r, 0, strerror(r)) + +<br>> > #Context test +               r = add_context(han, ctx, "sched_switch", "channel0") +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) +             #Any channel +          r =<br>> > add_context(han, ctx, "sched_wakeup", None) +          self.assertGreaterEqual(r,<br>> > 0, strerror(r)) +         #All events +           r = add_context(han, ctx, None, None) +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +               #Def. channel attr +<br>> > channel_set_default_attr(dom, chattr) +         channel_set_default_attr(None,<br>> > None) + +             #Ses Daemon alive +             r = session_daemon_alive() +<br>> > self.assertTrue(r == 1 or r == 0, strerror(r)) + +              #Setting trace group +<br>> > r = set_tracing_group("testing") +          self.assertGreaterEqual(r, 0,<br>> > strerror(r)) + + +             r = start("test_otherf") +            self.assertGreaterEqual(r,<br>> > 0, strerror(r)) +         time.sleep(2) + +               r = stop("test_otherf") +<br>> > self.assertGreaterEqual(r, 0, strerror(r)) + +           del han + +             r =<br>> > destroy("test_otherf") +               self.assertGreaterEqual(r, 0, strerror(r)) + + <br>> > +if __name__ == "__main__": +      # CHECK IF ROOT +       if os.geteuid() == 0: +<br>> > #Make sure session names don't already exist: +<br>> > destroy("test_kernel_event") +          destroy("test_kernel_all_events") +<br>> > destroy("test_ust_all_events") +             destroy("test_ust_event") +<br>> > destroy("test_otherf") + +           unittest.main() +       else: +         print('Script must<br>> > be run as root')<br>> -----BEGIN PGP SIGNATURE-----<br>> Version: GnuPG v1.4.12 (GNU/Linux)<br>> <br>> iQEcBAEBAgAGBQJQGCc4AAoJEELoaioR9I02f68IAKCipHU8psxIkXyUECveu57F<br>> 1ZPe9wzanUrb5eaiLH07mmbVJf/1Bu08eLfiuu1naaV0ZZIa2DenTXHcuC4orGbE<br>> /8KVBYidgDWIzY8lJOnw6wg+zB2ibnfTqtyhNE9Rqgesq6o776QfFgSkqzfQq/2m<br>> BxOsE1jKzx6JbgdquO32KBAyQAgyQu8Z9aJUYgAd3peqrx19pwnWhgnY88rtAzNi<br>> 5ktGj6btK4HAcQ62Q8pmTTaOR0y5sBb7STDYF2pcNMPU3TeLBjkRhl/djva0C7t/<br>> hPiL8IVT4AYC0y72Oof0kuSgaGIyHAxujAGHeOnOQP3KXhAvrow/bhJodbIo3pU=<br>> =lEVV<br>> -----END PGP SIGNATURE-----<br></div>                                          </div></body>
</html>