英文:
Code crashes when put into separate functions within a class
问题
这段代码存在两个版本,第一个版本将所有内容放在类的__init__
函数中,而第二个版本将内容分成两个函数:viewerInit
和viewerRefresh
。第一个版本正常工作,但第二个版本在鼠标悬停在Pangolin查看器窗口时崩溃。
问题可能与Python的垃圾收集机制有关。在第二个版本中,您将初始化代码移到了viewerInit
函数中,但是在__init__
函数完成后,viewerInit
函数的局部变量可能被垃圾收集,导致一些资源被释放或者指针失效。这可能是导致程序崩溃的原因。
您可以尝试在viewerInit
函数内部添加self
前缀来确保相关变量是实例变量,而不是局部变量,以防止它们被垃圾回收。例如:
self.pm = pango.ProjectionMatrix(640, 480, 420, 420, 320, 240, 0.1, 1000)
self.mv = pango.ModelViewLookAt(-0, 0.5, -3, 0, 0, 0, pango.AxisY)
这样可能会解决程序崩溃的问题。如果问题仍然存在,请考虑进一步调查与资源管理和垃圾收集相关的问题。
英文:
I've ran into an odd situation in Python where code works if I put everything in the __init__
function of a class, but if I break it up into functions within the class, the otherwise identical code crashes. Here is my current example:
This works:
# SimpleDisplay5.py
import faulthandler
import pypangolin as pango
import OpenGL.GL as gl
import numpy as np
import time
class Display3D(object):
def __init__(self):
self.win = pango.CreateWindowAndBind('Pangolin Viewer', 640, 480)
gl.glEnable(gl.GL_DEPTH_TEST)
pm = pango.ProjectionMatrix(640, 480, 420, 420, 320, 240, 0.1, 1000)
mv = pango.ModelViewLookAt(-0, 0.5, -3, 0, 0, 0, pango.AxisY)
self.s_cam = pango.OpenGlRenderState(pm, mv)
ui_width = 180
handler = pango.Handler3D(self.s_cam)
self.d_cam = (
pango.CreateDisplay()
.SetBounds(
pango.Attach(0),
pango.Attach(1),
pango.Attach.Pix(ui_width),
pango.Attach(1),
-640.0 / 480.0,
)
.SetHandler(handler)
)
self.points = np.random.uniform(-1.0, 1.0, (100, 3)).astype(np.float32)
gl.glPointSize(5)
gl.glColor3f(1.0, 0.0, 0.0) # red
while not pango.ShouldQuit():
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
self.d_cam.Activate(self.s_cam)
pango.glDrawPoints(self.points)
pango.FinishFrame()
# end while
# end function
# end class
def main():
faulthandler.enable()
np.set_printoptions(suppress=True)
disp3d = Display3D()
while True:
time.sleep(0.5)
# end while
# end function
if __name__ == "__main__":
main()
This crashes with a segmentation fault:
# SimpleDisplay6.py
import faulthandler
import pypangolin as pango
import OpenGL.GL as gl
import numpy as np
import time
class Display3D(object):
def __init__(self):
self.viewerInit()
self.viewerRefresh()
# end function
def viewerInit(self):
self.win = pango.CreateWindowAndBind('Pangolin Viewer', 640, 480)
gl.glEnable(gl.GL_DEPTH_TEST)
pm = pango.ProjectionMatrix(640, 480, 420, 420, 320, 240, 0.1, 1000)
mv = pango.ModelViewLookAt(-0, 0.5, -3, 0, 0, 0, pango.AxisY)
self.s_cam = pango.OpenGlRenderState(pm, mv)
ui_width = 180
handler = pango.Handler3D(self.s_cam)
self.d_cam = (
pango.CreateDisplay()
.SetBounds(
pango.Attach(0),
pango.Attach(1),
pango.Attach.Pix(ui_width),
pango.Attach(1),
-640.0 / 480.0,
)
.SetHandler(handler)
)
self.points = np.random.uniform(-1.0, 1.0, (100, 3)).astype(np.float32)
gl.glPointSize(5)
gl.glColor3f(1.0, 0.0, 0.0) # red
# end function
def viewerRefresh(self):
while not pango.ShouldQuit():
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
self.d_cam.Activate(self.s_cam)
pango.glDrawPoints(self.points)
pango.FinishFrame()
# end while
# end function
# end class
def main():
faulthandler.enable()
np.set_printoptions(suppress=True)
disp3d = Display3D()
while True:
time.sleep(0.5)
# end while
# end function
if __name__ == "__main__":
main()
Specifically, the 2nd program crashes when I mouse over the Pangolin viewer window. Here is the terminal output for the 2nd program:
$ python3 SimpleDisplay6.py
Fatal Python error: Segmentation fault
Current thread 0x00007f4384b05740 (most recent call first):
File "SimpleDisplay6.py", line 54 in viewerRefresh
File "SimpleDisplay6.py", line 14 in __init__
File "SimpleDisplay6.py", line 64 in main
File "SimpleDisplay6.py", line 73 in <module>
Segmentation fault (core dumped)
Line 54 in the 2nd program is:
pango.FinishFrame()
Note that the only difference between the 2 programs is in the 2nd, I divided up the __init__
content into 2 separate functions. Can somebody explain what is going on here or how this is even possible? Thinking of how this would break down into CPython, I would have figured it should have been identical.
I did post a question in the Pangolin viewer repo https://github.com/stevenlovegrove/Pangolin/issues/861, but the more I consider the situation I'm not sure this is a Pangolin concern since the 1st example works.
Moreover, I recall something very similar happening before when I attempted to call OpenCV functions from within a Qt frame (I don't have the code for that currently however).
I should probably also mention I'm aware the while True
in main()
is never reached in either program, I left that code in since my eventual plan was to start the Pangolin viewer on a separate thread when I get this current problem worked out.
Any suggestions as to the cause of this or what I should check next?
答案1
得分: 1
在这个 Python 扩展中,我完全不了解,但有间接证据表明,在调用 pango.glDrawPoints
和/或 pango.FinishFrame
时,pango.ProjectionMatrix
、pango.ModelViewLookAt
和 pango.Handler3D
中的一个或多个对象必须仍然处于 活动状态。这可以说是 pango
中的一个 错误;通常的期望是只要存在 任何 相关的 Python 对象,它就会使这些 Python 对象(或它们的底层 C++ 对象)保持活动状态。
英文:
With the loud disclaimer that I know nothing about this Python extension, the circumstantial evidence is that one or more of the pango.ProjectionMatrix
, pango.ModelViewLookAt
, and pango.Handler3D
objects must still be alive during the calls to pango.glDrawPoints
and/or pango.FinishFrame
. This is arguably a bug in pango
; the usual expectation is that it keeps the Python objects (or their coordinate C++ objects) alive so long as any relevant Python object is alive.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论