Skip to content

Commit 3fbbb46

Browse files
committed
Continue previous threading issue part3
1 parent a5247c3 commit 3fbbb46

File tree

1 file changed

+48
-9
lines changed

1 file changed

+48
-9
lines changed

python_issue.py

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,43 @@
3535
it will never be since the specific Thread is dead... Also if this dead Thread remains in
3636
the _limbo dictionary (small inconsistency since it will be return in case of threading.enumarate()).
3737
38-
When the thread is killed inside before `_started.set()`, we always get this weird error message:
38+
When the thread is killed inside before `_started.set()`, we always get a weird error message:
3939
"Exception ignored in thread started by: <A method>"
4040
This comes from the `thread_run` (C code) calling `_PyErr_WriteUnraisableMsg`
41-
At first glance, it seems that the ignored Exception is a MemoryError that skip part of the `_bootstrap_inner` method
41+
At first glance, it seems that the ignored Exception is a MemoryError that happens before or that
42+
the beginning of the `_bootstrap_inner` method (before `_started.set()` obviously).
43+
If we put sys.unraisablehook to get more information, it is always due to a MemoryError:
44+
45+
--- Unraisable Exception Caught ---
46+
Full Traceback:
47+
Traceback (most recent call last):
48+
File "/home/odoo/Documents/Pythons/py12/lib/python3.12/threading.py", line 1062, in _bootstrap_inner
49+
File "/home/odoo/Documents/Pythons/py12/lib/python3.12/threading.py", line 1051, in _set_tstate_lock
50+
self._tstate_lock = _set_sentinel()
51+
^^^^^^^^^^^^^^^
52+
RuntimeError: can't allocate lock
53+
------------------------------------
54+
Most of the case, Python cannot call the hook at all since it needs some memory to do so and then terminated
55+
with a error like this: Exception ignored in sys.unraisablehook: <function bulletproof_unraisable_hook at 0x7d87eff923e0>
56+
57+
Note that we also get a traceback from inside _bootstrap_inner if the memory exaustion happens inside of it:
58+
Traceback (most recent call last):
59+
File "/home/odoo/Documents/Pythons/py12/lib/python3.12/threading.py", line 1033, in _bootstrap
60+
self._bootstrap_inner()
61+
File "/home/odoo/Documents/Pythons/py12/lib/python3.12/threading.py", line 1080, in _bootstrap_inner
62+
self._delete()
63+
File "/home/odoo/Documents/Pythons/py12/lib/python3.12/threading.py", line 1112, in _delete
64+
del _active[get_ident()]
65+
~~~~~~~^^^^^^^^^^^^^
66+
KeyError: 139703676303040
67+
=> Make sense since the thread isn't inside the active at this point.
68+
4269
43-
What we tried:
70+
Other try:
4471
- Increasing the stack_size to force Python to only accept create new Thread when more
4572
memory is available on the stack. That's doesn't seems to work even with a hug number...
4673
Does this method even work ?? Signature is odd and the doc is incomplete ??
74+
=> Stack memory isn't the Problem. Heap memory is ...
4775
4876
- Catch the MemoryError, to sleep + gc after in order to force free memory => doesn't work better
4977
@@ -80,19 +108,30 @@
80108
81109
TODO:
82110
- Check inside the ignored Exception with a debugger C
83-
- Check works stack_size
84-
-
85111
86112
"""
87-
threading.stack_size(33000)
88113

89-
print("PID: ", os.getpid(), " Stack Size ", threading.stack_size())
114+
def unraisable_hook(unraisable):
115+
# This part might fail under memory exhaustion
116+
tb_str = "".join(traceback.format_exception(
117+
unraisable.exc_type, unraisable.exc_value, unraisable.exc_traceback
118+
))
119+
print(f"""
120+
--- Unraisable Exception Caught ---
121+
Object: {unraisable.object}
122+
Full Traceback:{tb_str}
123+
-----------------------------------""")
124+
125+
# Set hook to have more detail
126+
sys.unraisablehook = unraisable_hook
127+
128+
# Set limit to avoid crash my computer :D
129+
resource.setrlimit(resource.RLIMIT_AS, (1_000_000_000, 1_500_000_000))
90130

131+
print("PID: ", os.getpid(), " Stack Size ", threading.stack_size())
91132
# print("Sleep 10 sec")
92133
# time.sleep(10)
93134

94-
resource.setrlimit(resource.RLIMIT_AS, (1_000_000_000, 1_500_000_000))
95-
96135
def memory_error():
97136
memory_issue_list = []
98137
while True:

0 commit comments

Comments
 (0)