ICudaEngine.get_tensor_shape() returns a trt.Dims object.
Iterating over it with tuple() / list() works fine in a plain Python
script but crashes the process hard (exit 134 SIGABRT or exit 139 SIGSEGV)
when the same code runs inside a GStreamer plugin loaded through the
PyGObject / GLib Python wrapper. No Python traceback is produced because
the fault occurs in native code.
Conditions required to reproduce
The crash only occurs when all three of the following are true at the same time:
| # | Condition | Why it matters |
|---|---|---|
| 1 | The engine was pre-converted from ONNX to a serialised TRT .engine file and is loaded at runtime via Runtime.deserialize_cuda_engine |
A freshly built engine (ONNX compiled in the same process) does not trigger the issue — the internal memory layout of the Dims object differs between the two paths |
| 2 | The code runs inside a GStreamer plugin loaded by the PyGObject / GLib Python wrapper (gi.repository) |
PyGObject installs its own allocator hooks that alter how Pybind11 objects interact with the Python sequence protocol; the same code in a plain Python script or pytest session is unaffected |
| 3 | The tensor rank is 4-D or higher | Lower-rank tensors happen to stay within the bounds that __iter__ over-reads, so the crash does not occur for them |
In practice this means the bug is easy to miss: unit tests that load the engine directly (without GStreamer) pass without error, and the crash only surfaces at runtime inside the pipeline.
Context: how trt.Dims is used
The shape read from get_tensor_shape is used to pre-allocate CuPy GPU
buffers for each I/O tensor, whose device pointers are then registered with
the execution context before calling execute_async_v3.
Passing the trt.Dims object directly to cp.zeros() is the natural
approach — CuPy accepts any sequence as the shape argument:
buf = cp.zeros(dims, dtype=dtype) # CuPy internally calls tuple(dims) → crash
CuPy converts the shape argument to a tuple internally, which triggers
trt.Dims.__iter__ and causes the crash — even though dims is never
explicitly converted in user code.
Where the crash does NOT appear
Running the following in an ordinary Python interpreter or pytest session completes without error:
import tensorrt as trt
trt_logger = trt.Logger(trt.Logger.WARNING)
with open("model.engine", "rb") as f, trt.Runtime(trt_logger) as rt:
engine = rt.deserialize_cuda_engine(f.read())
for i in range(engine.num_io_tensors):
name = engine.get_tensor_name(i)
dims = engine.get_tensor_shape(name)
shape = tuple(dims) # works here
print(name, shape)
Where the crash DOES appear
Minimal GStreamer BaseTransform plugin that triggers it:
import gi
gi.require_version("Gst", "1.0")
gi.require_version("GstBase", "1.0")
from gi.repository import Gst, GstBase
import tensorrt as trt
Gst.init(None)
class MyTransform(GstBase.BaseTransform):
__gstmetadata__ = ("Test", "Transform", "Test", "Author")
__gsttemplates__ = ()
def do_transform_ip(self, buffer):
# engine loaded earlier via trt.Runtime.deserialize_cuda_engine
for i in range(self.engine.num_io_tensors):
name = self.engine.get_tensor_name(i)
dims = self.engine.get_tensor_shape(name)
shape = tuple(dims) # ← SIGSEGV / exit 139 for 4-D tensors
return Gst.FlowReturn.OK
Running a pipeline that processes a single buffer through MyTransform
terminates with:
Process finished with exit code 139 (SIGSEGV)
or occasionally exit code 134 (SIGABRT).
Why does trt.Dims.__iter__ behave differently inside a PyGObject-loaded
process, and what is the correct way to safely read the tensor shape?
Environment: Ubuntu 24.04 · Python 3.12 · GStreamer 1.26.5 ·
tensorrt / tensorrt_bindings · CuPy