Форум сайта python.su
py.user.nextВ моей ситуации сегфолт происходит не ровно в одном и том же месте. Может случиться не только после 10000 раз, но и 10001, 10022, 14522 и даже 456789 раз. Нет закономерности…
Набираешь “10000 c” и он проходит 10000 раз без остановки, а потом останавливается.
Офлайн
С закомментированным notify() нашел сегфолты в двух местах кода. Об одном из них раскажу:
def setupDirtyCatherForObject(self, obj, exclude): print obj if obj in exclude: return print 'library/DialogBase.py 2-30_2_1' print obj.children() print 'library/DialogBase.py 2-30_2_2' for child in obj.children(): print 'library/DialogBase.py 2-30_3' if isinstance(child, QtGui.QLabel) or child in exclude: pass elif isinstance(child, CDateEdit): self.connect(child, SIGNAL('dateChanged(QDate)'), self.on_dateEditChanged) elif isinstance(child, QtGui.QLineEdit): self.connect(child, SIGNAL('textChanged(QString)'), self.on_lineEditChanged) elif isinstance(child, QtGui.QTextEdit): self.connect(child, SIGNAL('textChanged()'), self.on_textEditChanged) elif isinstance(child, QtGui.QDateEdit): self.connect(child, SIGNAL('dateChanged(QDate)'), self.on_dateEditChanged) elif isinstance(child, QtGui.QComboBox): self.connect(child, SIGNAL('currentIndexChanged(int)'), self.on_comboBoxChanged) elif isinstance(child, QtGui.QCheckBox): self.connect(child, SIGNAL('stateChanged(int)'), self.on_checkBoxChanged) elif isinstance(child, QtGui.QSpinBox): self.connect(child, SIGNAL('valueChanged(int)'), self.on_spinBoxChanged) elif isinstance(child, QAbstractItemModel): self.connect(child, SIGNAL('dataChanged(QModelIndex, QModelIndex)'), self.on_abstractdataModelDataChanged) self.connect(child, SIGNAL('rowsInserted(QModelIndex, int, int)'), self.on_abstractdataModelDataChanged) self.connect(child, SIGNAL('rowsMoved(QModelIndex, int, int, QModelIndex, int)'), self.on_abstractdataModelDataChanged) self.connect(child, SIGNAL('rowsRemoved(QModelIndex, int, int)'), self.on_abstractdataModelDataChanged) else: self.setupDirtyCatherForObject(child, exclude)
print 'library/DialogBase.py 2-30_2_1' print obj.children() print 'library/DialogBase.py 2-30_2_2'
Офлайн
Vadyесли стабильно падает ,как вариант можно поместить либы со старой сборки в отдельную папку и добавить
решил перейти на более современную линуксовую ОС.
Офлайн
Нашел вторую закономерную причину сегфолта.
Открываю форму одного человека, ничего не меняя данные, закрываю.
То же самое повторяю несколько раз до сегфолта.
Анализ показал, что сегфолт произошел после полного выполнения сигнала (даже принт, который самый последний из строк в функции, отобразился):
def on_tabWidget_currentChanged(self, index):
Отредактировано Vady (Сен. 4, 2017 18:13:59)
Офлайн
Сигнал случайно не "destroyed()" называется?
Офлайн
Rodegast
Сигнал случайно не “destroyed()” называется?
Отредактировано Vady (Сен. 4, 2017 18:14:12)
Офлайн
Нашел вторую функцию, в которой произошел сегфолт.
И причем именно на obj.objectName()
Из принтов я вижу только:
'VisibleControlMixin.py 1-7_8'
Вот код функции:
@classmethod def updateVisibleState(cls, children, invisibleObjectsNameList): """ Обновляет состояние видимости всех объектов из списка children и их дочерних подобъектов. :param children: список объектов, для которых необходимо обновить состояние видимости :type children: list (of QObject) :param invisibleObjectsNameList: список имен объектов, которые необходимо скрыть :type invisibleObjectsNameList: list (of string) """ needProcessingList = [children] processedNameList = [] while needProcessingList: objList = needProcessingList.pop(0) for obj in objList: if isinstance(obj, QtGui.QTabWidget): processedNameList.extend(cls.hideTabWidgets(obj, invisibleObjectsNameList)) if isinstance(obj, QtGui.QWidget): print 'VisibleControlMixin.py 1-7_8' print obj.objectName() print 'VisibleControlMixin.py 1-7_8-1' objectName = forceString(obj.objectName()) if objectName in processedNameList: continue if objectName in invisibleObjectsNameList: obj.setVisible(False) if isinstance(obj, QtGui.QLabel): buddy = obj.buddy() if isinstance(buddy, QtGui.QWidget): buddy.setVisible(False) continue objChildren = obj.children() if objChildren: # добавить в стек просмотра дочерние элементы текущего виджета с обновлением частей имени needProcessingList.append(objChildren)
<PyQt4.QtGui.QScrollBar object at 0xad385adc>
<PyQt4.QtGui.QWidget object at 0xac9cc4f4>
<PyQt4.QtGui.QPushButton object at 0xaa1f4fa4>
Отредактировано Vady (Сен. 4, 2017 23:33:59)
Офлайн
Есть позитивный сдвиг! В функцию def setupDirtyCatherForObject(self, obj, exclude) добавил следующие строчки:
elif isinstance(child, QtGui.QScrollBar): pass elif isinstance(child, QtGui.QPushButton): pass
def setupDirtyCatherForObject(self, obj, exclude): print obj if obj in exclude: return for child in obj.children(): if isinstance(child, QtGui.QLabel) or child in exclude: pass elif isinstance(child, CDateEdit): self.connect(child, SIGNAL('dateChanged(QDate)'), self.on_dateEditChanged) elif isinstance(child, QtGui.QLineEdit): self.connect(child, SIGNAL('textChanged(QString)'), self.on_lineEditChanged) elif isinstance(child, QtGui.QTextEdit): self.connect(child, SIGNAL('textChanged()'), self.on_textEditChanged) elif isinstance(child, QtGui.QDateEdit): self.connect(child, SIGNAL('dateChanged(QDate)'), self.on_dateEditChanged) elif isinstance(child, QtGui.QComboBox): self.connect(child, SIGNAL('currentIndexChanged(int)'), self.on_comboBoxChanged) elif isinstance(child, QtGui.QCheckBox): self.connect(child, SIGNAL('stateChanged(int)'), self.on_checkBoxChanged) elif isinstance(child, QtGui.QSpinBox): self.connect(child, SIGNAL('valueChanged(int)'), self.on_spinBoxChanged) elif isinstance(child, QAbstractItemModel): self.connect(child, SIGNAL('dataChanged(QModelIndex, QModelIndex)'), self.on_abstractdataModelDataChanged) self.connect(child, SIGNAL('rowsInserted(QModelIndex, int, int)'), self.on_abstractdataModelDataChanged) self.connect(child, SIGNAL('rowsMoved(QModelIndex, int, int, QModelIndex, int)'), self.on_abstractdataModelDataChanged) self.connect(child, SIGNAL('rowsRemoved(QModelIndex, int, int)'), self.on_abstractdataModelDataChanged) elif isinstance(child, QtGui.QScrollBar): pass elif isinstance(child, QtGui.QPushButton): pass else: self.setupDirtyCatherForObject(child, exclude)
if isinstance(obj, QtGui.QScrollBar): continue if isinstance(obj, QtGui.QTPushButton): continue
@classmethod def updateVisibleState(cls, children, invisibleObjectsNameList): """ Обновляет состояние видимости всех объектов из списка children и их дочерних подобъектов. :param children: список объектов, для которых необходимо обновить состояние видимости :type children: list (of QObject) :param invisibleObjectsNameList: список имен объектов, которые необходимо скрыть :type invisibleObjectsNameList: list (of string) """ needProcessingList = [children] processedNameList = [] while needProcessingList: objList = needProcessingList.pop(0) for obj in objList: if isinstance(obj, QtGui.QScrollBar): continue if isinstance(obj, QtGui.QTPushButton): continue if isinstance(obj, QtGui.QTabWidget): processedNameList.extend(cls.hideTabWidgets(obj, invisibleObjectsNameList)) if isinstance(obj, QtGui.QWidget): print 'VisibleControlMixin.py 1-7_8' print obj.objectName() print 'VisibleControlMixin.py 1-7_8-1' objectName = forceString(obj.objectName()) if objectName in processedNameList: continue if objectName in invisibleObjectsNameList: obj.setVisible(False) if isinstance(obj, QtGui.QLabel): buddy = obj.buddy() if isinstance(buddy, QtGui.QWidget): buddy.setVisible(False) continue objChildren = obj.children() if objChildren: # добавить в стек просмотра дочерние элементы текущего виджета с обновлением частей имени needProcessingList.append(objChildren)
Отредактировано Vady (Сен. 6, 2017 23:11:51)
Офлайн
Кое-что нашел по этой проблеме.
Чтобы смоделировать проблему, открываем форму, в которой происходит такая проблема, и закрываем. И повторяем несколько раз - происходит Segmentation Fault.
Опытным путем установил: если в методе, который вызывается в момент закрытия формы, удалить строчку sip.delete(dialog), то сегфолт не происходит. Но от этого после 30 минут работы объем занимаемой программой памяти вырос до 2Гб! Вернул строчку. Далее в файле, где происходит создание окна формы, закомментировал в классе диалогового окна всё содержимое методов _init_() и destroy(). По результатам теста сегфолтов нет. Последовательно раскомментировал строчки. После того как раскомментировал self.addModels('Visits', CF02512VisitsModel(self)), произошел сегфолт. Далее раскомментировал строчку del self.modelVisits внутри метода destroy() - сегфолт прекратился. Из этого сделал вывод: неудаленные старые модели и впоследствии созданные заново - одна из возможных причин сегфолта.
Далее раскомментировал self.addModels('ActionsSummary', CFxxxActionsSummaryModel(self, True)), предусмотрительно раскомментировав и в destroy() строчку del self.modelActionsSummary - произошел сегфолт. В ходе изучения принципа работы данного класса выяснил, что одна подмодель этой модели нигде по завершении работы не удаляется:
class CActionsSummaryModel(CInDocTableModel): class CUetCol(CFloatInDocTableCol): def __init__(self, model): CFloatInDocTableCol.__init__(self, u'УЕТ', 'amount', 6, precision=2) self.model = model
if hasattr(self.modelActionsSummary, 'colUET'): del self.modelActionsSummary.colUet.model
Офлайн