mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 19:02:13 +07:00
PyDev: Don't use thread.ident because a new thread may end up having the same id of an old thread.
GitOrigin-RevId: 63fbcd2fe5ae1f46d93c496d1e7b2016f85a7d07
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5e42077a11
commit
f8ef1eaa95
@@ -713,9 +713,6 @@ class _NewThreadStartupWithTrace:
|
||||
# This is not a threading.Thread but a Dummy thread (so, get it as a dummy thread using
|
||||
# currentThread).
|
||||
t = threading.currentThread()
|
||||
|
||||
if t.ident is None:
|
||||
t._set_ident()
|
||||
|
||||
if not getattr(t, 'is_pydev_daemon_thread', False):
|
||||
thread_id = get_current_thread_id(t)
|
||||
|
||||
@@ -5,18 +5,18 @@ use_cython = os.getenv('PYDEVD_USE_CYTHON', None)
|
||||
|
||||
if use_cython == 'YES':
|
||||
# We must import the cython version if forcing cython
|
||||
from _pydevd_bundle.pydevd_cython_wrapper import PyDBAdditionalThreadInfo, set_additional_thread_info, _set_additional_thread_info_lock, _thread_ident_to_additional_info # @UnusedImport
|
||||
from _pydevd_bundle.pydevd_cython_wrapper import PyDBAdditionalThreadInfo, set_additional_thread_info, _set_additional_thread_info_lock # @UnusedImport
|
||||
|
||||
elif use_cython == 'NO':
|
||||
# Use the regular version if not forcing cython
|
||||
from _pydevd_bundle.pydevd_additional_thread_info_regular import PyDBAdditionalThreadInfo, set_additional_thread_info, _set_additional_thread_info_lock, _thread_ident_to_additional_info # @UnusedImport @Reimport
|
||||
from _pydevd_bundle.pydevd_additional_thread_info_regular import PyDBAdditionalThreadInfo, set_additional_thread_info, _set_additional_thread_info_lock # @UnusedImport @Reimport
|
||||
|
||||
elif use_cython is None:
|
||||
# Regular: use fallback if not found (message is already given elsewhere).
|
||||
try:
|
||||
from _pydevd_bundle.pydevd_cython_wrapper import PyDBAdditionalThreadInfo, set_additional_thread_info, _set_additional_thread_info_lock, _thread_ident_to_additional_info
|
||||
from _pydevd_bundle.pydevd_cython_wrapper import PyDBAdditionalThreadInfo, set_additional_thread_info, _set_additional_thread_info_lock
|
||||
except ImportError:
|
||||
from _pydevd_bundle.pydevd_additional_thread_info_regular import PyDBAdditionalThreadInfo, set_additional_thread_info, _set_additional_thread_info_lock, _thread_ident_to_additional_info # @UnusedImport
|
||||
from _pydevd_bundle.pydevd_additional_thread_info_regular import PyDBAdditionalThreadInfo, set_additional_thread_info, _set_additional_thread_info_lock # @UnusedImport
|
||||
else:
|
||||
raise RuntimeError('Unexpected value for PYDEVD_USE_CYTHON: %s (accepted: YES, NO)' % (use_cython,))
|
||||
|
||||
|
||||
@@ -121,7 +121,6 @@ class PyDBAdditionalThreadInfo(object):
|
||||
from _pydev_imps._pydev_saved_modules import threading
|
||||
_set_additional_thread_info_lock = threading.Lock()
|
||||
|
||||
_thread_ident_to_additional_info = {}
|
||||
|
||||
def set_additional_thread_info(thread):
|
||||
try:
|
||||
@@ -132,13 +131,9 @@ def set_additional_thread_info(thread):
|
||||
with _set_additional_thread_info_lock:
|
||||
# If it's not there, set it within a lock to avoid any racing
|
||||
# conditions.
|
||||
thread_ident = thread.ident
|
||||
if thread_ident is None:
|
||||
sys.stderr.write('thread.ident *must* be set at this point (set_additional_thread_info).')
|
||||
raise AssertionError('thread.ident *must* be set at this point (set_additional_thread_info).')
|
||||
additional_info = _thread_ident_to_additional_info.get(thread_ident)
|
||||
additional_info = getattr(thread, 'additional_info', None)
|
||||
if additional_info is None:
|
||||
additional_info = _thread_ident_to_additional_info[thread_ident] = PyDBAdditionalThreadInfo()
|
||||
additional_info = PyDBAdditionalThreadInfo()
|
||||
thread.additional_info = additional_info
|
||||
|
||||
return additional_info
|
||||
|
||||
@@ -291,9 +291,8 @@ def clear_cached_thread_id(thread):
|
||||
pass
|
||||
|
||||
|
||||
# Besides the cache in the thread, we create a cache from the thread ident -> thread id so that
|
||||
# if we have a Thread and later a DummyThread for the same ident we can obtain the same id.
|
||||
_thread_ident_to_thread_id = {}
|
||||
# Don't let threads be collected (so that id(thread) is guaranteed to be unique).
|
||||
_thread_id_to_thread_found = {}
|
||||
|
||||
|
||||
def _get_or_compute_thread_id_with_lock(thread, is_current_thread):
|
||||
@@ -303,26 +302,13 @@ def _get_or_compute_thread_id_with_lock(thread, is_current_thread):
|
||||
if tid is not None:
|
||||
return tid
|
||||
|
||||
try:
|
||||
thread_ident = thread.ident
|
||||
if thread_ident is None:
|
||||
raise AttributeError()
|
||||
except AttributeError:
|
||||
if not is_current_thread:
|
||||
# When getting from another thread (i.e.: not current), the thread.ident *must* be
|
||||
# there (when it's made visible in the threading module the ident is already set).
|
||||
raise AssertionError('Did not expect thread.ident to be None when gotten from another thread.')
|
||||
_thread_id_to_thread_found[id(thread)] = thread
|
||||
|
||||
# If we're too early in the thread bootstrap process,
|
||||
# the thread ident could be still unset in the Thread.
|
||||
thread_ident = thread_get_ident()
|
||||
try:
|
||||
tid = _thread_ident_to_thread_id[thread_ident]
|
||||
except KeyError:
|
||||
pid = get_pid()
|
||||
tid = 'pid_%s_id_%s' % (pid, id(thread))
|
||||
# Note: don't use thread.ident because a new thread may have the
|
||||
# same id from an old thread.
|
||||
pid = get_pid()
|
||||
tid = 'pid_%s_id_%s' % (pid, id(thread))
|
||||
|
||||
_thread_ident_to_thread_id[thread_ident] = tid
|
||||
thread.__pydevd_id__ = tid
|
||||
|
||||
return tid
|
||||
|
||||
@@ -127,7 +127,6 @@ cdef class PyDBAdditionalThreadInfo:
|
||||
from _pydev_imps._pydev_saved_modules import threading
|
||||
_set_additional_thread_info_lock = threading.Lock()
|
||||
|
||||
_thread_ident_to_additional_info = {}
|
||||
|
||||
def set_additional_thread_info(thread):
|
||||
try:
|
||||
@@ -138,13 +137,9 @@ def set_additional_thread_info(thread):
|
||||
with _set_additional_thread_info_lock:
|
||||
# If it's not there, set it within a lock to avoid any racing
|
||||
# conditions.
|
||||
thread_ident = thread.ident
|
||||
if thread_ident is None:
|
||||
sys.stderr.write('thread.ident *must* be set at this point (set_additional_thread_info).')
|
||||
raise AssertionError('thread.ident *must* be set at this point (set_additional_thread_info).')
|
||||
additional_info = _thread_ident_to_additional_info.get(thread_ident)
|
||||
additional_info = getattr(thread, 'additional_info', None)
|
||||
if additional_info is None:
|
||||
additional_info = _thread_ident_to_additional_info[thread_ident] = PyDBAdditionalThreadInfo()
|
||||
additional_info = PyDBAdditionalThreadInfo()
|
||||
thread.additional_info = additional_info
|
||||
|
||||
return additional_info
|
||||
@@ -765,19 +760,19 @@ cdef class PyDBFrame:
|
||||
# ok, hit breakpoint, now, we have to discover if it is a conditional breakpoint
|
||||
# lets do the conditional stuff here
|
||||
if stop or exist_result:
|
||||
eval_result = False
|
||||
if breakpoint.has_condition:
|
||||
eval_result = handle_breakpoint_condition(main_debugger, info, breakpoint, new_frame)
|
||||
if not eval_result:
|
||||
# No need to reset frame.f_trace to keep the same trace function.
|
||||
return self.trace_dispatch
|
||||
|
||||
if breakpoint.expression is not None:
|
||||
handle_breakpoint_expression(breakpoint, info, new_frame)
|
||||
if breakpoint.is_logpoint and info.pydev_message is not None and len(info.pydev_message) > 0:
|
||||
cmd = main_debugger.cmd_factory.make_io_message(info.pydev_message + os.linesep, '1')
|
||||
main_debugger.writer.add_command(cmd)
|
||||
# No need to reset frame.f_trace to keep the same trace function.
|
||||
return self.trace_dispatch
|
||||
|
||||
if breakpoint.has_condition and not eval_result:
|
||||
# No need to reset frame.f_trace to keep the same trace function.
|
||||
return self.trace_dispatch
|
||||
|
||||
if is_call and frame.f_code.co_name in ('<module>', '<lambda>'):
|
||||
# If we find a call for a module, it means that the module is being imported/executed for the
|
||||
@@ -1195,14 +1190,12 @@ cdef class TopLevelThreadTracerOnlyUnhandledExceptions:
|
||||
|
||||
# IFDEF CYTHON -- DONT EDIT THIS FILE (it is automatically generated)
|
||||
cdef class TopLevelThreadTracerNoBackFrame:
|
||||
#
|
||||
cdef public object _frame_trace_dispatch;
|
||||
cdef public tuple _args;
|
||||
cdef public object _try_except_info;
|
||||
cdef public object _last_exc_arg;
|
||||
cdef public set _raise_lines;
|
||||
cdef public int _last_raise_line;
|
||||
#
|
||||
def __init__(self, frame_trace_dispatch, tuple args):
|
||||
self._frame_trace_dispatch = frame_trace_dispatch
|
||||
self._args = args
|
||||
|
||||
@@ -47,8 +47,6 @@ global_cache_frame_skips = mod.global_cache_frame_skips
|
||||
|
||||
_set_additional_thread_info_lock = mod._set_additional_thread_info_lock
|
||||
|
||||
_thread_ident_to_additional_info = mod._thread_ident_to_additional_info
|
||||
|
||||
fix_top_level_trace_and_get_trace_func = mod.fix_top_level_trace_and_get_trace_func
|
||||
|
||||
version = getattr(mod, 'version', 0)
|
||||
|
||||
@@ -8,7 +8,7 @@ from _pydevd_frame_eval.pydevd_modify_bytecode import insert_code
|
||||
from pydevd_file_utils import get_abs_path_real_path_and_base_from_file, NORM_PATHS_AND_BASE_CONTAINER
|
||||
from _pydevd_bundle.pydevd_trace_dispatch import fix_top_level_trace_and_get_trace_func
|
||||
|
||||
from _pydevd_bundle.pydevd_additional_thread_info import _set_additional_thread_info_lock, _thread_ident_to_additional_info
|
||||
from _pydevd_bundle.pydevd_additional_thread_info import _set_additional_thread_info_lock
|
||||
from _pydevd_bundle.pydevd_cython cimport PyDBAdditionalThreadInfo
|
||||
|
||||
get_file_type = DONT_TRACE.get
|
||||
@@ -55,9 +55,9 @@ cdef class ThreadInfo:
|
||||
with _set_additional_thread_info_lock:
|
||||
# If it's not there, set it within a lock to avoid any racing
|
||||
# conditions.
|
||||
additional_info = _thread_ident_to_additional_info.get(thread_ident)
|
||||
additional_info = getattr(thread, 'additional_info', None)
|
||||
if additional_info is None:
|
||||
additional_info = _thread_ident_to_additional_info[thread_ident] = PyDBAdditionalThreadInfo()
|
||||
additional_info = PyDBAdditionalThreadInfo()
|
||||
t.additional_info = additional_info
|
||||
self.additional_info = additional_info
|
||||
self.fully_initialized = True
|
||||
|
||||
Reference in New Issue
Block a user