Повреждение памяти при выходе (или глупая ошибка пользователя) - PullRequest
0 голосов
/ 29 мая 2018

У меня проблема с тем, что объекты, содержащие импортированные модули Python, повреждены, но только после явного вызова sys.exit().Это также с перебоями.Я удалил большую часть кода, за исключением «стандартного» модуля pyusb (я использовал самую последнюю версию этого).На самом деле происходит очень мало.

Если программа вызывает sys.exit (), тогда некоторые идентификаторы объектов меняются на значения мусора.Если я пропущу это, то ошибок не будет!

Это действительно ошибка в 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 или свежим git pull из pyusb-1.0.2

1 Ответ

0 голосов
/ 29 мая 2018

При выходе из интерпретатора Python среда выполнения срывается, и порядок удаления объектов не является чем-то, на что вы можете положиться.На самом деле, даже не гарантируется, что __del__() методы будут вызываться вообще при выходе из интерпретатора.

Объекты, к которым пользовательский доступ __del__ должен получить доступ (включая другие модули), возможно, уже удалены или установленыв None, что приведет к возникновению именно тех исключений, которые вы видите здесь (у объекта 'NoneType' нет атрибута ...)

На самом деле это не «повреждение памяти», это просто плохой код, написанный дляInstrument класс.Любой необходимый контекст установки / разрыва должен управляться с помощью __enter__ и __exit__, поскольку __del__ не подходит для этой цели.Таким образом, эта проблема более или менее является ошибкой в ​​Instrument.Этот код, возможно, можно улучшить, воспользовавшись гарантией модели данных, задокументированной здесь :

Python гарантирует, что глобальные переменные, имя которых начинается с одного подчеркивания, будут удалены из их модуля до того, как другие глобальныеудалены;если нет других ссылок на такие глобальные переменные, это может помочь гарантировать, что импортированные модули все еще будут доступны во время вызова метода __del__().

...