diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py
index 19b08cd206b943c1716801a1ae0e6924e255351b..f4a3119f0ef5c6c82a1da89decec7be6c6eeab75 100644
--- a/pyopencl/cffi_cl.py
+++ b/pyopencl/cffi_cl.py
@@ -12,7 +12,8 @@ class _CArray(object):
         self.size = _ffi.new('uint32_t *')
 
     def __del__(self):
-        _lib._free(self.ptr[0])
+        if self.ptr != _ffi.NULL:
+            _lib._free(self.ptr[0])
 
     def __getitem__(self, key):
         return self.ptr[0].__getitem__(key)
@@ -70,6 +71,13 @@ class RuntimeError(Error):
 def _handle_error(error):
     if error == _ffi.NULL:
         return
+    if error.other == 1:
+        # non-pyopencl exceptions are handled here
+        import exceptions
+        e = exceptions.RuntimeError(_ffi.string(error.msg))
+        _lib._free(error.msg)
+        _lib._free(error)
+        raise e
     if error.code == status_code.MEM_OBJECT_ALLOCATION_FAILURE:
         klass = MemoryError
     elif error.code <= status_code.INVALID_VALUE:
@@ -79,11 +87,15 @@ def _handle_error(error):
     else:
         klass = Error
     e = klass(_ffi.string(error.routine), error.code, _ffi.string(error.msg))
+    _lib._free(error.routine)
+    _lib._free(error.msg)
     _lib._free(error)
     raise e
 # }}}
 
 class _Common(object):
+    ptr = _ffi.NULL
+    
     @classmethod
     def _c_class_type(cls):
         return getattr(_lib, 'CLASS_%s' % cls._id.upper())
diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp
index acd2eb6217bfe3ca90f02aee008bff3fc53d5542..7b967e2d6d3aeeebb5406ebe8445ab76a67dc182 100644
--- a/src/c_wrapper/wrap_cl.cpp
+++ b/src/c_wrapper/wrap_cl.cpp
@@ -21,16 +21,25 @@
 #define PYOPENCL_PRINT_CALL_TRACE_INFO(NAME, EXTRA_INFO) /*nothing*/
 #endif
 
-#define C_HANDLE_ERROR(OPERATION)		\
-  try {						\
-    OPERATION					\
-      } catch(pyopencl::error& e) {		\
-    MALLOC(::error, error, 1);			\
-    error->routine = e.routine();		\
-    error->msg = e.what();			\
-    error->code = e.code();			\
-    return error;				\
-  }						
+#define C_HANDLE_ERROR(OPERATION)			\
+  try {							\
+    OPERATION						\
+      } catch(const pyopencl::error& e) {		\
+    MALLOC(::error, error, 1);				\
+    error->routine = pyopencl::_copy_str(e.routine());	\
+    error->msg = pyopencl::_copy_str(e.what());		\
+    error->code = e.code();				\
+    error->other = 0;					\
+    return error;					\
+  } catch(const std::exception& e) {			\
+    /* non-pyopencl exceptions shall be */		\
+    /* converted as well */				\
+    MALLOC(::error, error, 1);				\
+    error->other = 1;					\
+    error->msg = pyopencl::_copy_str(e.what());		\
+    return error;					\
+  }							\
+  
 
 // TODO Py_BEGIN_ALLOW_THREADS \ Py_END_ALLOW_THREADS below
 #define PYOPENCL_CALL_GUARDED_THREADED(NAME, ARGLIST)	\
@@ -312,7 +321,8 @@ namespace pyopencl
 {
   char *_copy_str(const std::string& str) {
     MALLOC(char, cstr, str.size() + 1);
-    strcpy(cstr, str.c_str());
+    std::size_t len = str.copy(cstr, str.size());
+    cstr[len] = '\0';
     return cstr;
   }
   
@@ -1648,8 +1658,10 @@ namespace pyopencl
       cl_int status_code;
 
       PYOPENCL_PRINT_CALL_TRACE("clCreateKernel");
+      std::cout << "HUH HAHAH" << std::endl;
       m_kernel = clCreateKernel(prg.data(), kernel_name.c_str(),
 				&status_code);
+      std::cout << "HU2" << std::endl;
       if (status_code != CL_SUCCESS)
 	throw pyopencl::error("clCreateKernel", status_code);
     }
diff --git a/src/c_wrapper/wrap_cl_core.h b/src/c_wrapper/wrap_cl_core.h
index efac2d69b709eacb87dd4ba83c2b4fd9f60c6a20..1a9ee9370ead1147b5922be2bf0bfd6e1e43be12 100644
--- a/src/c_wrapper/wrap_cl_core.h
+++ b/src/c_wrapper/wrap_cl_core.h
@@ -4,6 +4,7 @@ typedef struct {
   const char *routine;
   const char *msg;
   cl_int code;
+  int other;
 } error;
 
 typedef enum {