Fix threads stop and join

This commit is contained in:
Elizaveta Shashkova
2015-10-24 16:21:26 +03:00
parent ebb3ccfe5b
commit b0aee00797
2 changed files with 51 additions and 15 deletions
@@ -1,10 +1,10 @@
import time
from pydevd_concurrency_analyser.pydevd_thread_wrappers import ObjectWrapper
from pydevd_concurrency_analyser.pydevd_thread_wrappers import ObjectWrapper, wrap_attr
import pydevd_file_utils
import pydevd_vars
from _pydev_filesystem_encoding import getfilesystemencoding
from pydevd_constants import DictContains, GetThreadId
from pydevd_constants import DictContains, GetThreadId, IS_PY3K
file_system_encoding = getfilesystemencoding()
@@ -86,8 +86,6 @@ def get_text_list_for_frame(frame):
return cmdTextList
def send_message(event_class, time, name, thread_id, type, event, file, line, frame, lock_id=0, parent=None):
dbg = GlobalDebuggerHolder.globalDbg
cmdTextList = ['<xml>']
@@ -135,7 +133,13 @@ class ThreadingLogger:
self_obj = frame.f_locals["self"]
if isinstance(self_obj, threading.Thread) or self_obj.__class__ == ObjectWrapper:
write_log = True
if hasattr(frame, "f_back") and frame.f_back is not None:
back = frame.f_back
if hasattr(back, "f_back") and back.f_back is not None:
back = back.f_back
if DictContains(back.f_locals, "self"):
if isinstance(back.f_locals["self"], threading.Thread):
write_log = True
try:
if write_log:
t = threadingCurrentThread()
@@ -146,31 +150,55 @@ class ThreadingLogger:
event_time = cur_time() - self.start_time
method_name = frame.f_code.co_name
if isinstance(self_obj, threading.Thread) and method_name in THREAD_METHODS:
if back_base not in DONT_TRACE_THREADING or \
(method_name in INNER_METHODS and back_base in INNER_FILES):
if isinstance(self_obj, threading.Thread):
if not hasattr(self_obj, "_pydev_run_patched"):
wrap_attr(self_obj, "run")
if (method_name in THREAD_METHODS) and (back_base not in DONT_TRACE_THREADING or \
(method_name in INNER_METHODS and back_base in INNER_FILES)):
thread_id = GetThreadId(self_obj)
name = self_obj.getName()
real_method = frame.f_code.co_name
parent = None
if real_method == "_stop":
# TODO: Python 2
if back_base in INNER_FILES and \
back.f_code.co_name == "_wait_for_tstate_lock":
back = back.f_back.f_back
real_method = "stop"
if hasattr(self_obj, "_pydev_join_called"):
parent = GetThreadId(t)
elif real_method == "join":
# join called in the current thread, not in self object
if not self_obj.is_alive():
return
thread_id = GetThreadId(t)
name = t.getName()
setattr(self_obj, "_pydev_join_called", True)
parent = None
if real_method in ("start", "stop"):
if real_method == "start":
parent = GetThreadId(t)
send_message("threading_event", event_time, name, thread_id, "thread",
real_method, back.f_code.co_filename, back.f_lineno, back, parent=parent)
# print(event_time, self_obj.getName(), thread_id, "thread",
# real_method, back.f_code.co_filename, back.f_lineno)
if method_name == "pydev_after_run_call":
if hasattr(frame, "f_back") and frame.f_back is not None:
back = frame.f_back
if hasattr(back, "f_back") and back.f_back is not None:
back = back.f_back
if DictContains(back.f_locals, "self"):
if isinstance(back.f_locals["self"], threading.Thread):
my_self_obj = frame.f_back.f_back.f_locals["self"]
my_back = frame.f_back.f_back
my_thread_id = GetThreadId(my_self_obj)
send_massage = True
if IS_PY3K and hasattr(my_self_obj, "_pydev_join_called"):
send_massage = False
# we can't detect stop after join in Python 2 yet
if send_massage:
send_message("threading_event", event_time, "Thread", my_thread_id, "thread",
"stop", my_back.f_code.co_filename, my_back.f_lineno, my_back, parent=None)
if self_obj.__class__ == ObjectWrapper:
if back_base in DONT_TRACE_THREADING:
# do not trace methods called from threading
@@ -206,6 +234,7 @@ class ThreadingLogger:
# print(event_time, t.getName(), GetThreadId(t), "lock",
# real_method, back.f_code.co_filename, back.f_lineno)
except Exception:
traceback.print_exc()
@@ -3,14 +3,21 @@ import _pydev_threading as threading
def wrapper(fun):
def pydev_after_run_call():
pass
def inner(*args, **kwargs):
print("start_new_thread called with params", args, kwargs)
thread = threading.currentThread()
thread.additionalInfo.save = True
return fun(*args, **kwargs)
fun(*args, **kwargs)
pydev_after_run_call()
return inner
def wrap_attr(obj, attr):
t_save_start = getattr(obj, attr)
setattr(obj, attr, wrapper(t_save_start))
setattr(obj, "_pydev_run_patched", True)
class ObjectWrapper(object):
def __init__(self, object):
self.wrapped_object = object