diff --git a/ACKNOWLEDGEMENTS b/ACKNOWLEDGEMENTS index fca1df1..86f4514 100644 --- a/ACKNOWLEDGEMENTS +++ b/ACKNOWLEDGEMENTS @@ -10,3 +10,6 @@ of the DTrace handles. Thanks to Alexander Richardson (https://github.com/arichardson) for doing a huge refactoring and looking into properly supporting python3. + +Thanks to Konrad Witaszczyk (https://github.com/kwitaszczyk) for looking into +properly freeing up DTrace resources. diff --git a/dtrace_cython/consumer.pyx b/dtrace_cython/consumer.pyx index fe10476..0401000 100644 --- a/dtrace_cython/consumer.pyx +++ b/dtrace_cython/consumer.pyx @@ -91,8 +91,10 @@ cdef int walk(const dtrace_aggdata_t * data, void * arg) with gil: # TODO: need to extend this. if rec.dtrd_size == sizeof(uint32_t): - keys.append((address)[0]) - if rec.dtrd_size == 20 * sizeof(uint64_t): + keys.append((address)[0]) + elif rec.dtrd_size == sizeof(uint64_t): + keys.append(( address)[0]) + elif rec.dtrd_size == 20 * sizeof(uint64_t): # case stack() has been used --> need to lookup symbols. for j in range(rec.dtrd_arg): pc = dereference(address) @@ -305,12 +307,12 @@ cdef class DTraceConsumer: """ self.chew_func = noop_chew if chew_func is None else chew_func self.chewrec_func = noop_chewrec if chewrec_func is None \ - else simple_chewrec + else chewrec_func self.out_func = noop_out if out_func is None else out_func self.walk_func = noop_walk if walk_func is None else walk_func cdef int err - if not hasattr(self, 'handle'): + if self.handle == NULL: # ensure we only grab 1 - cython might call init twice, of more. self.handle = dtrace_open(3, 0, &err) if self.handle == NULL: @@ -329,8 +331,9 @@ cdef class DTraceConsumer: """ Release DTrace handle. """ - if hasattr(self, 'handle') and self.handle != NULL: + if self.handle != NULL: dtrace_close(self.handle) + self.handle = NULL cpdef compile(self, str script): """ @@ -429,13 +432,13 @@ cdef class DTraceContinuousConsumer: """ self.chew_func = noop_chew if chew_func is None else chew_func self.chewrec_func = noop_chewrec if chewrec_func is None \ - else simple_chewrec + else chewrec_func self.out_func = noop_out if out_func is None else out_func self.walk_func = noop_walk if walk_func is None else walk_func self.script = script.encode("utf-8") cdef int err - if not hasattr(self, 'handle'): + if self.handle == NULL: # ensure we only grab 1 - cython might call init twice, of more. self.handle = dtrace_open(3, 0, &err) if self.handle == NULL: @@ -454,9 +457,10 @@ cdef class DTraceContinuousConsumer: """ Release DTrace handle. """ - if hasattr(self, 'handle') and self.handle != NULL: + if self.handle != NULL: dtrace_stop(self.handle) dtrace_close(self.handle) + self.handle = NULL cpdef go(self): """ diff --git a/dtrace_cython/dtrace_h.pxd b/dtrace_cython/dtrace_h.pxd index df4c6a2..cad75e1 100644 --- a/dtrace_cython/dtrace_h.pxd +++ b/dtrace_cython/dtrace_h.pxd @@ -103,7 +103,7 @@ cdef extern from "dtrace.h": ctypedef struct dtrace_syminfo_t: const char * dts_object const char * dts_name - long bla + long dts_id # from dtrace.h ctypedef int dtrace_handle_buffered_f(const dtrace_bufdata_t * buf_data, void * arg) diff --git a/setup.py b/setup.py index 0978356..6f573ea 100644 --- a/setup.py +++ b/setup.py @@ -17,18 +17,20 @@ from Cython.Build import build_ext, cythonize extra_args = {} if platform.system().lower().startswith("freebsd"): - # On FreeBSD the dtrace headers are not installed by default. - src_dir = os.getenv("FREEBSD_SRC_DIR", "/usr/src") - if not os.path.exists(os.path.join(src_dir, "sys/cddl")): - raise ImportError("Cannot find FreeBSD DTrace headers") - extra_args["include_dirs"] = [ - os.path.join(src_dir, - "sys/cddl/compat/opensolaris"), - os.path.join(src_dir, - "sys/cddl/contrib/opensolaris/uts/common"), - os.path.join(src_dir, - "cddl/contrib/opensolaris/lib/libdtrace/common"), - ] + # On older FreeBSD versions the dtrace headers are not + # installed by default, so we need to find the full sources. + if not os.path.exists("/usr/include/dtrace.h"): + src_dir = os.getenv("FREEBSD_SRC_DIR", "/usr/src") + if not os.path.exists(os.path.join(src_dir, "sys/cddl")): + raise ImportError("Cannot find FreeBSD DTrace headers") + extra_args["include_dirs"] = [ + os.path.join(src_dir, + "sys/cddl/compat/opensolaris"), + os.path.join(src_dir, + "sys/cddl/contrib/opensolaris/uts/common"), + os.path.join(src_dir, + "cddl/contrib/opensolaris/lib/libdtrace/common"), + ] if os.getenv("ENABLE_ASAN", None) is not None: extra_args["extra_compile_args"] = ["-fsanitize=address"] extra_args["extra_link_args"] = ["-fsanitize=address"] @@ -52,13 +54,13 @@ setup(name='python-dtrace', - version='0.0.11', + version='0.0.15', description='DTrace consumer for Python based on libdtrace. Use Python' ' as DTrace Consumer and Provider! See the homepage for' ' more information.', license='MIT', keywords='DTrace', - url='http://tmetsch.github.com/python-dtrace/', + url='http://tmetsch.github.io/python-dtrace/', packages=['dtrace_ctypes'], cmdclass=BUILD_EXTENSION, ext_modules=EXT_MODULES,