summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
3b2be70)
Babeltrace API calls can explicitly return the MEMORY_ERROR status,
which is currently converted to a bt2.Error in Python. If this
bt2.Error goes back to the native side of the bindings, is is converted
back to the ERROR status. This is not ideal, as the status value should
stay MEMORY_ERROR when unwinding the stack.
Also, when creation functions fail (return NULL/None), we currently
raise a CreationError. Those creation functions only return NULL/None
if there were memory issues, there is not other way they can
legitimately fail (otherwise they would return a status). So it would
make sense for this to be reported as a MEMORY_ERROR.
To address these two issues, this patch:
- renames bt2.CreationError to bt2.MemoryError
- makes utils._handle_func_status raise a bt2.MemoryError when receiving
the MEMORY_ERROR status
- makes the native bindings return MEMORY_ERROR when catching a
bt2.MemoryError
Since there's no easy way to generate an actual MemoryError, I tested
this manually by hacking bt_graph_create to make it fail.
Change-Id: I4969e8ccd9618d8361fe45d0973df980bc9b7abd
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1751
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
14 files changed:
from bt2.clock_snapshot import _UnknownClockSnapshot
from bt2.clock_snapshot import _UnknownClockSnapshot
-class CreationError(Error):
- '''Raised when object creation fails due to memory issues.'''
+class MemoryError(Error):
+ '''Raised when an operation fails due to memory issues.'''
class InvalidObject(Exception):
class InvalidObject(Exception):
- raise bt2.CreationError(
"cannot create component class '{}'".format(class_name)
)
"cannot create component class '{}'".format(class_name)
)
tc_ptr = native_bt.trace_class_create(ptr)
if tc_ptr is None:
tc_ptr = native_bt.trace_class_create(ptr)
if tc_ptr is None:
- raise bt2.CreationError('could not create trace class')
+ raise bt2.MemoryError('could not create trace class')
tc = bt2._TraceClass._create_from_ptr(tc_ptr)
tc._assigns_automatic_stream_class_id = assigns_automatic_stream_class_id
tc = bt2._TraceClass._create_from_ptr(tc_ptr)
tc._assigns_automatic_stream_class_id = assigns_automatic_stream_class_id
cc_ptr = native_bt.clock_class_create(ptr)
if cc_ptr is None:
cc_ptr = native_bt.clock_class_create(ptr)
if cc_ptr is None:
- raise bt2.CreationError('could not create clock class')
+ raise bt2.MemoryError('could not create clock class')
cc = bt2.clock_class._ClockClass._create_from_ptr(cc_ptr)
cc = bt2.clock_class._ClockClass._create_from_ptr(cc_ptr)
def _check_create_status(self, ptr):
if ptr is None:
def _check_create_status(self, ptr):
if ptr is None:
- raise bt2.CreationError(
'cannot create {} field class object'.format(self._NAME.lower())
)
'cannot create {} field class object'.format(self._NAME.lower())
)
ptr = native_bt.graph_create()
if ptr is None:
ptr = native_bt.graph_create()
if ptr is None:
- raise bt2.CreationError('cannot create graph object')
+ raise bt2.MemoryError('cannot create graph object')
)
if msg_iter_ptr is None:
)
if msg_iter_ptr is None:
- raise bt2.CreationError('cannot create output port message iterator')
+ raise bt2.MemoryError('cannot create output port message iterator')
return bt2.message_iterator._OutputPortMessageIterator(msg_iter_ptr)
return bt2.message_iterator._OutputPortMessageIterator(msg_iter_ptr)
ptr = self._create_range_set()
if ptr is None:
ptr = self._create_range_set()
if ptr is None:
- raise bt2.CreationError('cannot create range set object')
+ raise bt2.MemoryError('cannot create range set object')
- raise bt2.CreationError('cannot create event message object')
+ raise bt2.MemoryError('cannot create event message object')
return bt2.message._EventMessage(ptr)
return bt2.message._EventMessage(ptr)
- raise bt2.CreationError('cannot create inactivity message object')
+ raise bt2.MemoryError('cannot create inactivity message object')
return bt2.message._MessageIteratorInactivityMessage(ptr)
return bt2.message._MessageIteratorInactivityMessage(ptr)
ptr = native_bt.message_stream_beginning_create(self._bt_ptr, stream._ptr)
if ptr is None:
ptr = native_bt.message_stream_beginning_create(self._bt_ptr, stream._ptr)
if ptr is None:
- raise bt2.CreationError('cannot create stream beginning message object')
+ raise bt2.MemoryError('cannot create stream beginning message object')
msg = bt2.message._StreamBeginningMessage(ptr)
msg = bt2.message._StreamBeginningMessage(ptr)
ptr = native_bt.message_stream_end_create(self._bt_ptr, stream._ptr)
if ptr is None:
ptr = native_bt.message_stream_end_create(self._bt_ptr, stream._ptr)
if ptr is None:
- raise bt2.CreationError('cannot create stream end message object')
+ raise bt2.MemoryError('cannot create stream end message object')
msg = bt2.message._StreamEndMessage(ptr)
msg = bt2.message._StreamEndMessage(ptr)
ptr = native_bt.message_packet_beginning_create(self._bt_ptr, packet._ptr)
if ptr is None:
ptr = native_bt.message_packet_beginning_create(self._bt_ptr, packet._ptr)
if ptr is None:
- raise bt2.CreationError('cannot create packet beginning message object')
+ raise bt2.MemoryError('cannot create packet beginning message object')
return bt2.message._PacketBeginningMessage(ptr)
return bt2.message._PacketBeginningMessage(ptr)
ptr = native_bt.message_packet_end_create(self._bt_ptr, packet._ptr)
if ptr is None:
ptr = native_bt.message_packet_end_create(self._bt_ptr, packet._ptr)
if ptr is None:
- raise bt2.CreationError('cannot create packet end message object')
+ raise bt2.MemoryError('cannot create packet end message object')
return bt2.message._PacketEndMessage(ptr)
return bt2.message._PacketEndMessage(ptr)
ptr = native_bt.message_discarded_events_create(self._bt_ptr, stream._ptr)
if ptr is None:
ptr = native_bt.message_discarded_events_create(self._bt_ptr, stream._ptr)
if ptr is None:
- raise bt2.CreationError('cannot discarded events message object')
+ raise bt2.MemoryError('cannot discarded events message object')
msg = bt2.message._DiscardedEventsMessage(ptr)
msg = bt2.message._DiscardedEventsMessage(ptr)
ptr = native_bt.message_discarded_packets_create(self._bt_ptr, stream._ptr)
if ptr is None:
ptr = native_bt.message_discarded_packets_create(self._bt_ptr, stream._ptr)
if ptr is None:
- raise bt2.CreationError('cannot discarded packets message object')
+ raise bt2.MemoryError('cannot discarded packets message object')
msg = bt2.message._DiscardedPacketsMessage(ptr)
msg = bt2.message._DiscardedPacketsMessage(ptr)
static PyObject *py_mod_bt2 = NULL;
static PyObject *py_mod_bt2_exc_error_type = NULL;
static PyObject *py_mod_bt2 = NULL;
static PyObject *py_mod_bt2_exc_error_type = NULL;
+static PyObject *py_mod_bt2_exc_memory_error = NULL;
static PyObject *py_mod_bt2_exc_try_again_type = NULL;
static PyObject *py_mod_bt2_exc_stop_type = NULL;
static PyObject *py_mod_bt2_exc_msg_iter_canceled_type = NULL;
static PyObject *py_mod_bt2_exc_try_again_type = NULL;
static PyObject *py_mod_bt2_exc_stop_type = NULL;
static PyObject *py_mod_bt2_exc_msg_iter_canceled_type = NULL;
py_mod_bt2_exc_error_type =
PyObject_GetAttrString(py_mod_bt2, "Error");
BT_ASSERT(py_mod_bt2_exc_error_type);
py_mod_bt2_exc_error_type =
PyObject_GetAttrString(py_mod_bt2, "Error");
BT_ASSERT(py_mod_bt2_exc_error_type);
+ py_mod_bt2_exc_memory_error =
+ PyObject_GetAttrString(py_mod_bt2, "MemoryError");
+ BT_ASSERT(py_mod_bt2_exc_memory_error);
py_mod_bt2_exc_try_again_type =
PyObject_GetAttrString(py_mod_bt2, "TryAgain");
BT_ASSERT(py_mod_bt2_exc_try_again_type);
py_mod_bt2_exc_try_again_type =
PyObject_GetAttrString(py_mod_bt2, "TryAgain");
BT_ASSERT(py_mod_bt2_exc_try_again_type);
log_exception_and_maybe_append_error(BT_LOG_WARNING, true,
self_component_class, self_component,
self_message_iterator, module_name);
log_exception_and_maybe_append_error(BT_LOG_WARNING, true,
self_component_class, self_component,
self_message_iterator, module_name);
- status = __BT_FUNC_STATUS_ERROR;
+
+ if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_memory_error)) {
+ status = __BT_FUNC_STATUS_MEMORY_ERROR;
+ } else {
+ status = __BT_FUNC_STATUS_ERROR;
+ }
self._ptr
)
if msg_iter_ptr is None:
self._ptr
)
if msg_iter_ptr is None:
- raise bt2.CreationError('cannot create message iterator object')
+ raise bt2.MemoryError('cannot create message iterator object')
return bt2.message_iterator._UserComponentInputPortMessageIterator(msg_iter_ptr)
return bt2.message_iterator._UserComponentInputPortMessageIterator(msg_iter_ptr)
ptr = native_bt.query_executor_create()
if ptr is None:
ptr = native_bt.query_executor_create()
if ptr is None:
- raise bt2.CreationError('cannot create query executor object')
+ raise bt2.MemoryError('cannot create query executor object')
packet_ptr = native_bt.packet_create(self._ptr)
if packet_ptr is None:
packet_ptr = native_bt.packet_create(self._ptr)
if packet_ptr is None:
- raise bt2.CreationError('cannot create packet object')
+ raise bt2.MemoryError('cannot create packet object')
return bt2.packet._Packet._create_from_ptr(packet_ptr)
return bt2.packet._Packet._create_from_ptr(packet_ptr)
- raise bt2.CreationError('cannot create stream object')
+ raise bt2.MemoryError('cannot create stream object')
stream = bt2.stream._Stream._create_from_ptr(stream_ptr)
stream = bt2.stream._Stream._create_from_ptr(stream_ptr)
trace_ptr = native_bt.trace_create(self._ptr)
if trace_ptr is None:
trace_ptr = native_bt.trace_create(self._ptr)
if trace_ptr is None:
- raise bt2.CreationError('cannot create trace class object')
+ raise bt2.MemoryError('cannot create trace class object')
trace = bt2.trace._Trace._create_from_ptr(trace_ptr)
trace = bt2.trace._Trace._create_from_ptr(trace_ptr)
def _check_create_status(self, ptr, type_name):
if ptr is None:
def _check_create_status(self, ptr, type_name):
if ptr is None:
- raise bt2.CreationError('cannot create {} field class'.format(type_name))
+ raise bt2.MemoryError('cannot create {} field class'.format(type_name))
def _create_integer_field_class(
self, create_func, py_cls, type_name, field_value_range, preferred_display_base
def _create_integer_field_class(
self, create_func, py_cls, type_name, field_value_range, preferred_display_base
- if (
- status == native_bt.__BT_FUNC_STATUS_ERROR
- or status == native_bt.__BT_FUNC_STATUS_MEMORY_ERROR
- ):
+ if status == native_bt.__BT_FUNC_STATUS_ERROR:
assert msg is not None
raise bt2.Error(msg)
assert msg is not None
raise bt2.Error(msg)
+ elif status == native_bt.__BT_FUNC_STATUS_MEMORY_ERROR:
+ assert msg is not None
+ raise bt2.MemoryError(msg)
elif status == native_bt.__BT_FUNC_STATUS_END:
if msg is None:
raise bt2.Stop
elif status == native_bt.__BT_FUNC_STATUS_END:
if msg is None:
raise bt2.Stop
def _check_create_status(self, ptr):
if ptr is None:
def _check_create_status(self, ptr):
if ptr is None:
- raise bt2.CreationError(
'cannot create {} value object'.format(self._NAME.lower())
)
'cannot create {} value object'.format(self._NAME.lower())
)