gpt4 book ai didi

python - 退出时内存损坏(或愚蠢的用户错误)

转载 作者:行者123 更新时间:2023-12-01 09:24:10 26 4
gpt4 key购买 nike

我遇到一个问题,即保存导入的 python 模块的对象被损坏,但仅在显式调用 sys.exit() 后才损坏。这也是间歇性的。除了“标准”pyusb 模块(我使用了该模块的最新版本)之外,我已经删除了大部分代码。实际上发生的事情很少。

如果程序调用 sys.exit(),则某些对象 ID 会更改为垃圾值。如果我忽略它,那么就不会有错误!

这真的是 Python 中的一个错误吗?这似乎不太可能。我做错了什么?

====主程序“bug_happens.py”

#!/usr/bin/python3

import sys

import usbtmc

scope = usbtmc.Instrument()
print('in Main')
print(' id of usbtmc.usb: 0x{:x}'.format(id(usbtmc.usb)))
print(' id of usbtmc.usb.util: 0x{:x}'.format(id(usbtmc.usb.util)))
print(' id of usbtmc.usb.util.dispose_resources: 0x{:x}'.format(id(usbtmc.usb.util.dispose_resources)))
print()

print('calling Exit()')
sys.exit()

===== 非常精简的 usbtmc 模块

"""
****** Very stripped down partial Version for debugging a memory corruption issue ******

Python USBTMC driver

Copyright (c) 2012-2017 Alex Forencich

...
"""

import usb.util

class Instrument(object):
def __init__(self, *args, **kwargs):

self.connected = False

print('usbtmc.Instrument created 0x{:x}'.format(id(self)))
print(' id of usb: 0x{:x}'.format(id(usb)))
print(' id of usb.util: 0x{:x}'.format(id(usb.util)))
print(' id of usb.util.dispose_resources: 0x{:x}'.format(id(usb.util.dispose_resources)))
print()

def __del__(self):
print('usbtmc.Instrument.__del__() called for 0x{:x}'.format(id(self)))
print(' id of usb: 0x{:x}'.format(id(usb)))
print(' id of usb.util: 0x{:x}'.format(id(usb.util)))
print(' id of usb.util.dispose_resources: 0x{:x}'.format(id(usb.util.dispose_resources)))
print(' end of usbtmc.Instrument.__del__()')
print()

================================================== =======

===== 很多时候这都可以正常工作:

usbtmc.Instrument created 0x7fee5775d9b0
id of usb: 0x7fee562800e8
id of usb.util: 0x7fee562247c8
id of usb.util.dispose_resources: 0x7fee561ad048

in Main
id of usbtmc.usb: 0x7fee562800e8
id of usbtmc.usb.util: 0x7fee562247c8
id of usbtmc.usb.util.dispose_resources: 0x7fee561ad048

calling Exit()
usbtmc.Instrument.__del__() called for 0x7fee5775d9b0
id of usb: 0x7fee562800e8
id of usb.util: 0x7fee562247c8
id of usb.util.dispose_resources: 0x7fee561ad048
end of usbtmc.Instrument.__del__()

================================================== =======

===== 大约 50% 的时间是这样做的:

usbtmc.Instrument created 0x7fec34b829b0
id of usb: 0x7fec336c3278
id of usb.util: 0x7fec335dbb88
id of usb.util.dispose_resources: 0x7fec335e5048

in Main
id of usbtmc.usb: 0x7fec336c3278
id of usbtmc.usb.util: 0x7fec335dbb88
id of usbtmc.usb.util.dispose_resources: 0x7fec335e5048

calling Exit()
usbtmc.Instrument.__del__() called for 0x7fec34b829b0
id of usb: 0xa40060
Exception ignored in: <bound method Instrument.__del__ of <usbtmc.Instrument object at 0x7fec34b829b0>>
Traceback (most recent call last):
File "/home/don/Electronics/Projects/HF_Meas/Scope_SA/Bug_usb_close/usbtmc.py", line 27, in __del__
AttributeError: 'NoneType' object has no attribute 'util'

================================================== =======

====== 有时它会这样做:

usbtmc.Instrument created 0x7ff75968c9b0
id of usb: 0x7ff7581af0e8
id of usb.util: 0x7ff7581537c8
id of usb.util.dispose_resources: 0x7ff7580dc048

in Main
id of usbtmc.usb: 0x7ff7581af0e8
id of usbtmc.usb.util: 0x7ff7581537c8
id of usbtmc.usb.util.dispose_resources: 0x7ff7580dc048

calling Exit()
usbtmc.Instrument.__del__() called for 0x7ff75968c9b0
id of usb: 0x7ff7581af0e8
id of usb.util: 0xa40060
Exception ignored in: <bound method Instrument.__del__ of <usbtmc.Instrument object at 0x7ff75968c9b0>>
Traceback (most recent call last):
File "/home/don/Electronics/Projects/HF_Meas/Scope_SA/Bug_usb_close/usbtmc.py", line 28, in __del__
AttributeError: 'NoneType' object has no attribute 'dispose_resources'

在 Mint 18.3 系统上运行 python3 3.5.1-3以及 python3-usb 1.0.0~b2-2 或 pyusb-1.0.2 的新 git pull

最佳答案

当Python解释器退出时,运行时将被拆除,并且对象删除的顺序不是您可以依赖的。事实上,甚至不能保证解释器退出时会调用 __del__() 方法。

自定义 __del__ 需要访问的对象(包括其他模块)可能已被删除或设置为 None,这将导致您所看到的异常这里('NoneType'对象没有属性...)

这并不是真正的“内存损坏”,它只是为 Instrument 类编写的糟糕代码。任何必要的设置/拆卸上下文都应使用 __enter____exit__ 进行管理,因为 __del__ 不适合此目的。所以,这个问题或多或少是 Instrument 中的一个错误。可以通过利用记录在案的数据模型保证来改进此代码 here :

Python guarantees that globals whose name begins with a single underscore are deleted from their module before other globals are deleted; if no other references to such globals exist, this may help in assuring that imported modules are still available at the time when the __del__() method is called.

关于python - 退出时内存损坏(或愚蠢的用户错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50574201/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com