New submission from Fish Wang <fish.t...@gmail.com>:
I come across this issue recently when developing a multi-threaded PySide2 (Qt) application. When I'm calling .copy() on a WeakValueDictionary, there is a high chance that my application crashes with the following stack backtrace: ------ Traceback (most recent call last): File "F:\angr\angr-management\angrmanagement\ui\widgets\qdisasm_graph.py", line 239, in mouseDoubleClickEvent block.on_mouse_doubleclicked(event.button(), self._to_graph_pos(event.pos())) File "F:\angr\angr-management\angrmanagement\ui\widgets\qblock.py", line 130, in on_mouse_doubleclicked obj.on_mouse_doubleclicked(button, pos) File "F:\angr\angr-management\angrmanagement\ui\widgets\qinstruction.py", line 128, in on_mouse_doubleclicked op.on_mouse_doubleclicked(button, pos) File "F:\angr\angr-management\angrmanagement\ui\widgets\qoperand.py", line 162, in on_mouse_doubleclicked self.disasm_view.jump_to(self._branch_target, src_ins_addr=self.insn.addr) File "F:\angr\angr-management\angrmanagement\ui\views\disassembly_view.py", line 258, in jump_to self._jump_to(addr) File "F:\angr\angr-management\angrmanagement\ui\views\disassembly_view.py", line 372, in _jump_to self._display_function(function) File "F:\angr\angr-management\angrmanagement\ui\views\disassembly_view.py", line 343, in _display_function vr = self.workspace.instance.project.analyses.VariableRecoveryFast(the_func) File "f:\angr\angr\angr\analyses\analysis.py", line 109, in __call__ oself.__init__(*args, **kwargs) File "f:\angr\angr\angr\analyses\variable_recovery\variable_recovery_fast.py", line 618, in __init__ self._analyze() File "f:\angr\angr\angr\analyses\forward_analysis.py", line 557, in _analyze self._analysis_core_graph() File "f:\angr\angr\angr\analyses\forward_analysis.py", line 580, in _analysis_core_graph changed, output_state = self._run_on_node(n, job_state) File "f:\angr\angr\angr\analyses\variable_recovery\variable_recovery_fast.py", line 712, in _run_on_node input_state = prev_state.merge(input_state, successor=node.addr) File "f:\angr\angr\angr\analyses\variable_recovery\variable_recovery_fast.py", line 488, in merge merged_register_region = self.register_region.copy().replace(replacements).merge(other.register_region, File "f:\angr\angr\angr\keyed_region.py", line 159, in copy kr._object_mapping = self._object_mapping.copy() File "D:\My Program Files\Python37\lib\weakref.py", line 174, in copy for key, wr in self.data.items(): RuntimeError: dictionary changed size during iteration ------ I went ahead and read the related methods in Lib\weakref.py, and it seems to me that the WeakValueDictionary.copy() method is missing the protection of an _IterationGuard: It is iterating through self.data.items(), which, might have entries removed because of GC during the iteration. It seems that this crash can be fixed by wrapping the iteration with `with _IterationGuard(self):`. It worked for me in my tests. If my above analysis is correct, the following methods all require protection of _IterationGuard (which are currently missing): - WeakValueDictionary.copy() - WeakValueDictionary.__deepcopy__() - WeakKeyDictionary.copy() - WeakKeyDictionary.__deepcopy__() Please let me know if this is a legitimate issue, in which case I will be happy to provide a patch. Thanks. ---------- components: Library (Lib) messages: 332734 nosy: Fish Wang priority: normal severity: normal status: open title: "RuntimeError: Dictionary changed size during iteration" when copying a WeakValueDictionary type: crash versions: Python 3.7 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue35615> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com