blob: 5cd96b1232ae80df76f0b2a51a0738cc16aec66e [file] [log] [blame]
Tor Norbye3a2425a2013-11-04 10:16:08 -08001#IMPORTANT: pydevd_constants must be the 1st thing defined because it'll keep a reference to the original sys._getframe
2from django_debug import DjangoLineBreakpoint
3from pydevd_signature import SignatureFactory
4from pydevd_frame import add_exception_to_frame
Tor Norbye3a2425a2013-11-04 10:16:08 -08005import pydev_imports
6from pydevd_breakpoints import * #@UnusedWildImport
7import fix_getpass
8
9from pydevd_comm import CMD_CHANGE_VARIABLE, \
10 CMD_EVALUATE_EXPRESSION, \
11 CMD_EXEC_EXPRESSION, \
12 CMD_GET_COMPLETIONS, \
13 CMD_GET_FRAME, \
14 CMD_GET_VARIABLE, \
15 CMD_LIST_THREADS, \
16 CMD_REMOVE_BREAK, \
17 CMD_RUN, \
18 CMD_SET_BREAK, \
19 CMD_SET_NEXT_STATEMENT,\
20 CMD_STEP_INTO, \
21 CMD_STEP_OVER, \
22 CMD_STEP_RETURN, \
23 CMD_THREAD_CREATE, \
24 CMD_THREAD_KILL, \
25 CMD_THREAD_RUN, \
26 CMD_THREAD_SUSPEND, \
27 CMD_RUN_TO_LINE, \
28 CMD_RELOAD_CODE, \
29 CMD_VERSION, \
30 CMD_CONSOLE_EXEC, \
31 CMD_ADD_EXCEPTION_BREAK, \
32 CMD_REMOVE_EXCEPTION_BREAK, \
33 CMD_LOAD_SOURCE, \
34 CMD_ADD_DJANGO_EXCEPTION_BREAK, \
35 CMD_REMOVE_DJANGO_EXCEPTION_BREAK, \
36 CMD_SMART_STEP_INTO,\
37 InternalChangeVariable, \
38 InternalGetCompletions, \
39 InternalEvaluateExpression, \
40 InternalConsoleExec, \
41 InternalGetFrame, \
42 InternalGetVariable, \
43 InternalTerminateThread, \
44 InternalRunThread, \
45 InternalStepThread, \
46 NetCommand, \
47 NetCommandFactory, \
48 PyDBDaemonThread, \
49 _queue, \
50 ReaderThread, \
51 SetGlobalDebugger, \
52 WriterThread, \
53 PydevdFindThreadById, \
54 PydevdLog, \
55 StartClient, \
56 StartServer, \
57 InternalSetNextStatementThread
58
59from pydevd_file_utils import NormFileToServer, GetFilenameAndBase
60import pydevd_file_utils
61import pydevd_vars
62import traceback
63import pydevd_vm_type
64import pydevd_tracing
65import pydevd_io
66import pydev_monkey
67from pydevd_additional_thread_info import PyDBAdditionalThreadInfo
68
69if USE_LIB_COPY:
70 import _pydev_time as time
71 import _pydev_threading as threading
72else:
73 import time
74 import threading
75
76import os
77
78
79threadingEnumerate = threading.enumerate
80threadingCurrentThread = threading.currentThread
81
82
83DONT_TRACE = {
84 #commonly used things from the stdlib that we don't want to trace
85 'threading.py':1,
86 'Queue.py':1,
87 'queue.py':1,
88 'socket.py':1,
89
90 #things from pydev that we don't want to trace
91 'pydevd_additional_thread_info.py':1,
92 'pydevd_comm.py':1,
93 'pydevd_constants.py':1,
94 'pydevd_exec.py':1,
95 'pydevd_exec2.py':1,
96 'pydevd_file_utils.py':1,
97 'pydevd_frame.py':1,
98 'pydevd_io.py':1 ,
99 'pydevd_resolver.py':1 ,
100 'pydevd_tracing.py':1 ,
101 'pydevd_signature.py':1,
102 'pydevd_utils.py':1,
103 'pydevd_vars.py':1,
104 'pydevd_vm_type.py':1,
105 'pydevd.py':1 ,
106 'pydevd_psyco_stub.py':1,
107 '_pydev_execfile.py':1,
108 '_pydev_jython_execfile.py':1
109 }
110
111if IS_PY3K:
112 #if we try to trace io.py it seems it can get halted (see http://bugs.python.org/issue4716)
113 DONT_TRACE['io.py'] = 1
114
115
116connected = False
117bufferStdOutToServer = False
118bufferStdErrToServer = False
119remote = False
120
121PyDBUseLocks = True
122
Tor Norbye92584642014-04-17 08:39:25 -0700123def isThreadAlive(t):
124 try:
125 alive = t.isAlive()
126 except:
127 alive = False #Workaround for Python 3.4 http://youtrack.jetbrains.com/issue/PY-12317
128 return alive
Tor Norbye3a2425a2013-11-04 10:16:08 -0800129
130#=======================================================================================================================
131# PyDBCommandThread
132#=======================================================================================================================
133class PyDBCommandThread(PyDBDaemonThread):
134
135 def __init__(self, pyDb):
136 PyDBDaemonThread.__init__(self)
137 self.pyDb = pyDb
138 self.setName('pydevd.CommandThread')
139
140 def OnRun(self):
141 for i in range(1, 10):
142 time.sleep(0.5) #this one will only start later on (because otherwise we may not have any non-daemon threads
143 if self.killReceived:
144 return
145
146 if self.dontTraceMe:
147 self.pyDb.SetTrace(None) # no debugging on this thread
148
149 try:
150 while not self.killReceived:
151 try:
152 self.pyDb.processInternalCommands()
153 except:
154 PydevdLog(0, 'Finishing debug communication...(2)')
155 time.sleep(0.5)
156 except:
157 pydev_log.debug(sys.exc_info()[0])
158
159 #only got this error in interpreter shutdown
160 #PydevdLog(0, 'Finishing debug communication...(3)')
161
162
163def killAllPydevThreads():
164 threads = threadingEnumerate()
165 for t in threads:
166 if hasattr(t, 'doKillPydevThread'):
167 t.doKillPydevThread()
168
169
170#=======================================================================================================================
171# PyDBCheckAliveThread
172#=======================================================================================================================
173class PyDBCheckAliveThread(PyDBDaemonThread):
174
175 def __init__(self, pyDb):
176 PyDBDaemonThread.__init__(self)
177 self.pyDb = pyDb
178 self.setDaemon(False)
179 self.setName('pydevd.CheckAliveThread')
180
181 def OnRun(self):
182 if self.dontTraceMe:
183 self.pyDb.SetTrace(None) # no debugging on this thread
184 while not self.killReceived:
185 if not self.pyDb.haveAliveThreads():
186 try:
187 pydev_log.debug("No alive threads, finishing debug session")
188 self.pyDb.FinishDebuggingSession()
189 killAllPydevThreads()
190 except:
191 traceback.print_exc()
192
Tor Norbye3a2425a2013-11-04 10:16:08 -0800193 self.killReceived = True
194 return
195
196 time.sleep(0.3)
197
198 def doKillPydevThread(self):
199 pass
200
201if USE_LIB_COPY:
202 import _pydev_thread as thread
203else:
204 try:
205 import thread
206 except ImportError:
207 import _thread as thread #Py3K changed it.
208
209_original_start_new_thread = thread.start_new_thread
210
211if getattr(thread, '_original_start_new_thread', None) is None:
212 thread._original_start_new_thread = thread.start_new_thread
213
214#=======================================================================================================================
215# NewThreadStartup
216#=======================================================================================================================
217class NewThreadStartup:
218
219 def __init__(self, original_func, args, kwargs):
220 self.original_func = original_func
221 self.args = args
222 self.kwargs = kwargs
223
224 def __call__(self):
225 global_debugger = GetGlobalDebugger()
226 global_debugger.SetTrace(global_debugger.trace_dispatch)
227 self.original_func(*self.args, **self.kwargs)
228
229thread.NewThreadStartup = NewThreadStartup
230
231#=======================================================================================================================
232# pydev_start_new_thread
233#=======================================================================================================================
234def _pydev_start_new_thread(function, args, kwargs={}):
235 '''
236 We need to replace the original thread.start_new_thread with this function so that threads started through
237 it and not through the threading module are properly traced.
238 '''
239 if USE_LIB_COPY:
240 import _pydev_thread as thread
241 else:
242 try:
243 import thread
244 except ImportError:
245 import _thread as thread #Py3K changed it.
246
247 return thread._original_start_new_thread(thread.NewThreadStartup(function, args, kwargs), ())
248
249class PydevStartNewThread(object):
250 def __get__(self, obj, type=None):
251 return self
252
253 def __call__(self, function, args, kwargs={}):
254 return _pydev_start_new_thread(function, args, kwargs)
255
256pydev_start_new_thread = PydevStartNewThread()
257
258#=======================================================================================================================
259# PyDB
260#=======================================================================================================================
261class PyDB:
262 """ Main debugging class
263 Lots of stuff going on here:
264
265 PyDB starts two threads on startup that connect to remote debugger (RDB)
266 The threads continuously read & write commands to RDB.
267 PyDB communicates with these threads through command queues.
268 Every RDB command is processed by calling processNetCommand.
269 Every PyDB net command is sent to the net by posting NetCommand to WriterThread queue
270
271 Some commands need to be executed on the right thread (suspend/resume & friends)
272 These are placed on the internal command queue.
273 """
274
275 RUNNING_THREAD_IDS = {} #this is a dict of thread ids pointing to thread ids. Whenever a command
276 #is passed to the java end that acknowledges that a thread was created,
277 #the thread id should be passed here -- and if at some time we do not find
278 #that thread alive anymore, we must remove it from this list and make
279 #the java side know that the thread was killed.
280
281 def __init__(self):
282 SetGlobalDebugger(self)
283 pydevd_tracing.ReplaceSysSetTraceFunc()
284 self.reader = None
285 self.writer = None
286 self.quitting = None
287 self.cmdFactory = NetCommandFactory()
288 self._cmd_queue = {} # the hash of Queues. Key is thread id, value is thread
289 self.breakpoints = {}
290 self.django_breakpoints = {}
291 self.exception_set = {}
292 self.always_exception_set = set()
293 self.django_exception_break = {}
294 self.readyToRun = False
295 self._main_lock = threading.Lock()
296 self._lock_running_thread_ids = threading.Lock()
297 self._finishDebuggingSession = False
298 self._terminationEventSent = False
299 self.force_post_mortem_stop = 0
300 self.signature_factory = None
301 self.SetTrace = pydevd_tracing.SetTrace
302
303 #this is a dict of thread ids pointing to thread ids. Whenever a command is passed to the java end that
304 #acknowledges that a thread was created, the thread id should be passed here -- and if at some time we do not
305 #find that thread alive anymore, we must remove it from this list and make the java side know that the thread
306 #was killed.
307 self._running_thread_ids = {}
308
309 def haveAliveThreads(self):
310 for t in threadingEnumerate():
Tor Norbye92584642014-04-17 08:39:25 -0700311 if not isinstance(t, PyDBDaemonThread) and isThreadAlive(t) and not t.isDaemon():
Tor Norbye3a2425a2013-11-04 10:16:08 -0800312 return True
313
314 return False
315
316 def FinishDebuggingSession(self):
317 self._finishDebuggingSession = True
318
319 def acquire(self):
320 if PyDBUseLocks:
321 self.lock.acquire()
322 return True
323
324 def release(self):
325 if PyDBUseLocks:
326 self.lock.release()
327 return True
328
329 def initializeNetwork(self, sock):
330 try:
331 sock.settimeout(None) # infinite, no timeouts from now on - jython does not have it
332 except:
333 pass
334 self.writer = WriterThread(sock)
335 self.reader = ReaderThread(sock)
336 self.writer.start()
337 self.reader.start()
338
339 time.sleep(0.1) # give threads time to start
340
341 def connect(self, host, port):
342 if host:
343 s = StartClient(host, port)
344 else:
345 s = StartServer(port)
346
347 self.initializeNetwork(s)
348
349
350 def getInternalQueue(self, thread_id):
351 """ returns internal command queue for a given thread.
352 if new queue is created, notify the RDB about it """
353 try:
354 return self._cmd_queue[thread_id]
355 except KeyError:
356 return self._cmd_queue.setdefault(thread_id, _queue.Queue()) #@UndefinedVariable
357
358
359 def postInternalCommand(self, int_cmd, thread_id):
360 """ if thread_id is *, post to all """
361 if thread_id == "*":
362 for k in self._cmd_queue.keys():
363 self._cmd_queue[k].put(int_cmd)
364
365 else:
366 queue = self.getInternalQueue(thread_id)
367 queue.put(int_cmd)
368
369 def checkOutputRedirect(self):
370 global bufferStdOutToServer
371 global bufferStdErrToServer
372
373 if bufferStdOutToServer:
374 initStdoutRedirect()
375 self.checkOutput(sys.stdoutBuf, 1) #@UndefinedVariable
376
377 if bufferStdErrToServer:
378 initStderrRedirect()
379 self.checkOutput(sys.stderrBuf, 2) #@UndefinedVariable
380
381 def checkOutput(self, out, outCtx):
382 '''Checks the output to see if we have to send some buffered output to the debug server
383
384 @param out: sys.stdout or sys.stderr
385 @param outCtx: the context indicating: 1=stdout and 2=stderr (to know the colors to write it)
386 '''
387
388 try:
389 v = out.getvalue()
390
391 if v:
392 self.cmdFactory.makeIoMessage(v, outCtx, self)
393 except:
394 traceback.print_exc()
395
396
397 def processInternalCommands(self):
398 '''This function processes internal commands
399 '''
400 curr_thread_id = GetThreadId(threadingCurrentThread())
401 program_threads_alive = {}
402 all_threads = threadingEnumerate()
403 program_threads_dead = []
404
405
406 self._main_lock.acquire()
407 try:
408
409 self.checkOutputRedirect()
410
411 self._lock_running_thread_ids.acquire()
412 try:
413 for t in all_threads:
414 thread_id = GetThreadId(t)
415
Tor Norbye92584642014-04-17 08:39:25 -0700416 if not isinstance(t, PyDBDaemonThread) and isThreadAlive(t):
Tor Norbye3a2425a2013-11-04 10:16:08 -0800417 program_threads_alive[thread_id] = t
418
419 if not DictContains(self._running_thread_ids, thread_id):
420 if not hasattr(t, 'additionalInfo'):
421 #see http://sourceforge.net/tracker/index.php?func=detail&aid=1955428&group_id=85796&atid=577329
422 #Let's create the additional info right away!
423 t.additionalInfo = PyDBAdditionalThreadInfo()
424 self._running_thread_ids[thread_id] = t
425 self.writer.addCommand(self.cmdFactory.makeThreadCreatedMessage(t))
426
427
428 queue = self.getInternalQueue(thread_id)
429 cmdsToReadd = [] #some commands must be processed by the thread itself... if that's the case,
430 #we will re-add the commands to the queue after executing.
431 try:
432 while True:
433 int_cmd = queue.get(False)
434 if int_cmd.canBeExecutedBy(curr_thread_id):
435 PydevdLog(2, "processing internal command ", str(int_cmd))
436 int_cmd.doIt(self)
437 else:
438 PydevdLog(2, "NOT processing internal command ", str(int_cmd))
439 cmdsToReadd.append(int_cmd)
440
441 except _queue.Empty: #@UndefinedVariable
442 for int_cmd in cmdsToReadd:
443 queue.put(int_cmd)
444 # this is how we exit
445
446
447 thread_ids = list(self._running_thread_ids.keys())
448 for tId in thread_ids:
449 if not DictContains(program_threads_alive, tId):
450 program_threads_dead.append(tId)
451 finally:
452 self._lock_running_thread_ids.release()
453
454 for tId in program_threads_dead:
455 try:
456 self.processThreadNotAlive(tId)
457 except:
458 sys.stderr.write('Error iterating through %s (%s) - %s\n' % (
459 program_threads_alive, program_threads_alive.__class__, dir(program_threads_alive)))
460 raise
461
462
463 if len(program_threads_alive) == 0:
464 self.FinishDebuggingSession()
465 for t in all_threads:
466 if hasattr(t, 'doKillPydevThread'):
467 t.doKillPydevThread()
468
469 finally:
470 self._main_lock.release()
471
472
473 def setTracingForUntracedContexts(self):
474 #Enable the tracing for existing threads (because there may be frames being executed that
475 #are currently untraced).
476 threads = threadingEnumerate()
477 for t in threads:
478 if not t.getName().startswith('pydevd.'):
479 #TODO: optimize so that we only actually add that tracing if it's in
480 #the new breakpoint context.
481 additionalInfo = None
482 try:
483 additionalInfo = t.additionalInfo
484 except AttributeError:
485 pass #that's ok, no info currently set
486
487 if additionalInfo is not None:
488 for frame in additionalInfo.IterFrames():
489 self.SetTraceForFrameAndParents(frame)
490 del frame
491
492
493 def processNetCommand(self, cmd_id, seq, text):
494 '''Processes a command received from the Java side
495
496 @param cmd_id: the id of the command
497 @param seq: the sequence of the command
498 @param text: the text received in the command
499
500 @note: this method is run as a big switch... after doing some tests, it's not clear whether changing it for
501 a dict id --> function call will have better performance result. A simple test with xrange(10000000) showed
502 that the gains from having a fast access to what should be executed are lost because of the function call in
503 a way that if we had 10 elements in the switch the if..elif are better -- but growing the number of choices
504 makes the solution with the dispatch look better -- so, if this gets more than 20-25 choices at some time,
505 it may be worth refactoring it (actually, reordering the ifs so that the ones used mostly come before
506 probably will give better performance).
507 '''
508
509 self._main_lock.acquire()
510 try:
511 try:
512 cmd = None
513 if cmd_id == CMD_RUN:
514 self.readyToRun = True
515
516 elif cmd_id == CMD_VERSION:
517 # response is version number
518 local_version, pycharm_os = text.split('\t', 1)
519
520 pydevd_file_utils.set_pycharm_os(pycharm_os)
521
522 cmd = self.cmdFactory.makeVersionMessage(seq)
523
524 elif cmd_id == CMD_LIST_THREADS:
525 # response is a list of threads
526 cmd = self.cmdFactory.makeListThreadsMessage(seq)
527
528 elif cmd_id == CMD_THREAD_KILL:
529 int_cmd = InternalTerminateThread(text)
530 self.postInternalCommand(int_cmd, text)
531
532 elif cmd_id == CMD_THREAD_SUSPEND:
533 #Yes, thread suspend is still done at this point, not through an internal command!
534 t = PydevdFindThreadById(text)
535 if t:
536 additionalInfo = None
537 try:
538 additionalInfo = t.additionalInfo
539 except AttributeError:
540 pass #that's ok, no info currently set
541
542 if additionalInfo is not None:
543 for frame in additionalInfo.IterFrames():
544 self.SetTraceForFrameAndParents(frame)
545 del frame
546
547 self.setSuspend(t, CMD_THREAD_SUSPEND)
548
549 elif cmd_id == CMD_THREAD_RUN:
550 t = PydevdFindThreadById(text)
551 if t:
552 thread_id = GetThreadId(t)
553 int_cmd = InternalRunThread(thread_id)
554 self.postInternalCommand(int_cmd, thread_id)
555
556 elif cmd_id == CMD_STEP_INTO or cmd_id == CMD_STEP_OVER or cmd_id == CMD_STEP_RETURN:
557 #we received some command to make a single step
558 t = PydevdFindThreadById(text)
559 if t:
560 thread_id = GetThreadId(t)
561 int_cmd = InternalStepThread(thread_id, cmd_id)
562 self.postInternalCommand(int_cmd, thread_id)
563
564 elif cmd_id == CMD_RUN_TO_LINE or cmd_id == CMD_SET_NEXT_STATEMENT or cmd_id == CMD_SMART_STEP_INTO:
565 #we received some command to make a single step
566 thread_id, line, func_name = text.split('\t', 2)
567 t = PydevdFindThreadById(thread_id)
568 if t:
569 int_cmd = InternalSetNextStatementThread(thread_id, cmd_id, line, func_name)
570 self.postInternalCommand(int_cmd, thread_id)
571
572
573 elif cmd_id == CMD_RELOAD_CODE:
574 #we received some command to make a reload of a module
575 module_name = text.strip()
576 from pydevd_reload import xreload
577 if not DictContains(sys.modules, module_name):
578 if '.' in module_name:
579 new_module_name = module_name.split('.')[-1]
580 if DictContains(sys.modules, new_module_name):
581 module_name = new_module_name
582
583 if not DictContains(sys.modules, module_name):
584 sys.stderr.write('pydev debugger: Unable to find module to reload: "'+module_name+'".\n')
585 sys.stderr.write('pydev debugger: This usually means you are trying to reload the __main__ module (which cannot be reloaded).\n')
586 sys.stderr.flush()
587
588 else:
589 sys.stderr.write('pydev debugger: Reloading: '+module_name+'\n')
590 sys.stderr.flush()
591 xreload(sys.modules[module_name])
592
593
594 elif cmd_id == CMD_CHANGE_VARIABLE:
595 #the text is: thread\tstackframe\tFRAME|GLOBAL\tattribute_to_change\tvalue_to_change
596 try:
597 thread_id, frame_id, scope, attr_and_value = text.split('\t', 3)
598
599 tab_index = attr_and_value.rindex('\t')
600 attr = attr_and_value[0:tab_index].replace('\t', '.')
601 value = attr_and_value[tab_index + 1:]
602 int_cmd = InternalChangeVariable(seq, thread_id, frame_id, scope, attr, value)
603 self.postInternalCommand(int_cmd, thread_id)
604
605 except:
606 traceback.print_exc()
607
608 elif cmd_id == CMD_GET_VARIABLE:
609 #we received some command to get a variable
610 #the text is: thread_id\tframe_id\tFRAME|GLOBAL\tattributes*
611 try:
612 thread_id, frame_id, scopeattrs = text.split('\t', 2)
613
614 if scopeattrs.find('\t') != -1: # there are attributes beyond scope
615 scope, attrs = scopeattrs.split('\t', 1)
616 else:
617 scope, attrs = (scopeattrs, None)
618
619 int_cmd = InternalGetVariable(seq, thread_id, frame_id, scope, attrs)
620 self.postInternalCommand(int_cmd, thread_id)
621
622 except:
623 traceback.print_exc()
624
625 elif cmd_id == CMD_GET_COMPLETIONS:
626 #we received some command to get a variable
627 #the text is: thread_id\tframe_id\tactivation token
628 try:
629 thread_id, frame_id, scope, act_tok = text.split('\t', 3)
630
631 int_cmd = InternalGetCompletions(seq, thread_id, frame_id, act_tok)
632 self.postInternalCommand(int_cmd, thread_id)
633
634 except:
635 traceback.print_exc()
636
637 elif cmd_id == CMD_GET_FRAME:
638 thread_id, frame_id, scope = text.split('\t', 2)
639
640 int_cmd = InternalGetFrame(seq, thread_id, frame_id)
641 self.postInternalCommand(int_cmd, thread_id)
642
643 elif cmd_id == CMD_SET_BREAK:
644 #func name: 'None': match anything. Empty: match global, specified: only method context.
645
646 #command to add some breakpoint.
647 # text is file\tline. Add to breakpoints dictionary
648 type, file, line, condition, expression = text.split('\t', 4)
649
650 if condition.startswith('**FUNC**'):
651 func_name, condition = condition.split('\t', 1)
652
653 #We must restore new lines and tabs as done in
654 #AbstractDebugTarget.breakpointAdded
655 condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n').\
656 replace("@_@TAB_CHAR@_@", '\t').strip()
657
658 func_name = func_name[8:]
659 else:
660 func_name = 'None' #Match anything if not specified.
661
662
663 file = NormFileToServer(file)
664
665 if not pydevd_file_utils.exists(file):
666 sys.stderr.write('pydev debugger: warning: trying to add breakpoint'\
667 ' to file that does not exist: %s (will have no effect)\n' % (file,))
668 sys.stderr.flush()
669
670 line = int(line)
671
672 if len(condition) <= 0 or condition is None or condition == "None":
673 condition = None
674
675 if len(expression) <= 0 or expression is None or expression == "None":
676 expression = None
677
678 if type == 'python-line':
679 breakpoint = LineBreakpoint(type, True, condition, func_name, expression)
680 breakpoint.add(self.breakpoints, file, line, func_name)
681 elif type == 'django-line':
682 breakpoint = DjangoLineBreakpoint(type, file, line, True, condition, func_name, expression)
683 breakpoint.add(self.django_breakpoints, file, line, func_name)
684 else:
685 raise NameError(type)
686
687 self.setTracingForUntracedContexts()
688
689 elif cmd_id == CMD_REMOVE_BREAK:
690 #command to remove some breakpoint
691 #text is file\tline. Remove from breakpoints dictionary
692 type, file, line = text.split('\t', 2)
693 file = NormFileToServer(file)
694 try:
695 line = int(line)
696 except ValueError:
697 pass
698
699 else:
700 found = False
701 try:
702 if type == 'django-line':
703 del self.django_breakpoints[file][line]
704 elif type == 'python-line':
705 del self.breakpoints[file][line] #remove the breakpoint in that line
706 else:
707 try:
708 del self.django_breakpoints[file][line]
709 found = True
710 except:
711 pass
712 try:
713 del self.breakpoints[file][line] #remove the breakpoint in that line
714 found = True
715 except:
716 pass
717
718 if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
719 sys.stderr.write('Removed breakpoint:%s - %s\n' % (file, line))
720 sys.stderr.flush()
721 except KeyError:
722 found = False
723
724 if not found:
725 #ok, it's not there...
726 if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
727 #Sometimes, when adding a breakpoint, it adds a remove command before (don't really know why)
728 sys.stderr.write("breakpoint not found: %s - %s\n" % (file, line))
729 sys.stderr.flush()
730
731 elif cmd_id == CMD_EVALUATE_EXPRESSION or cmd_id == CMD_EXEC_EXPRESSION:
732 #command to evaluate the given expression
733 #text is: thread\tstackframe\tLOCAL\texpression
734 thread_id, frame_id, scope, expression, trim = text.split('\t', 4)
735 int_cmd = InternalEvaluateExpression(seq, thread_id, frame_id, expression,
736 cmd_id == CMD_EXEC_EXPRESSION, int(trim) == 1)
737 self.postInternalCommand(int_cmd, thread_id)
738
739 elif cmd_id == CMD_CONSOLE_EXEC:
740 #command to exec expression in console, in case expression is only partially valid 'False' is returned
741 #text is: thread\tstackframe\tLOCAL\texpression
742
743 thread_id, frame_id, scope, expression = text.split('\t', 3)
744
745 int_cmd = InternalConsoleExec(seq, thread_id, frame_id, expression)
746 self.postInternalCommand(int_cmd, thread_id)
747
748 elif cmd_id == CMD_ADD_EXCEPTION_BREAK:
749 exception, notify_always, notify_on_terminate = text.split('\t', 2)
750
751 eb = ExceptionBreakpoint(exception, notify_always, notify_on_terminate)
752
753 self.exception_set[exception] = eb
754
755 if eb.notify_on_terminate:
756 update_exception_hook(self)
757 if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
758 pydev_log.error("Exceptions to hook on terminate: %s\n" % (self.exception_set,))
759
760 if eb.notify_always:
761 self.always_exception_set.add(exception)
762 if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
763 pydev_log.error("Exceptions to hook always: %s\n" % (self.always_exception_set,))
764 self.setTracingForUntracedContexts()
765
766 elif cmd_id == CMD_REMOVE_EXCEPTION_BREAK:
767 exception = text
768 try:
769 del self.exception_set[exception]
770 self.always_exception_set.remove(exception)
771 except:
Tor Norbye1fff8e22014-03-10 13:13:45 -0700772 pydev_log.debug("Error while removing exception"%sys.exc_info()[0]);
Tor Norbye3a2425a2013-11-04 10:16:08 -0800773 update_exception_hook(self)
774
775 elif cmd_id == CMD_LOAD_SOURCE:
776 path = text
777 try:
778 f = open(path, 'r')
779 source = f.read()
780 self.cmdFactory.makeLoadSourceMessage(seq, source, self)
781 except:
782 return self.cmdFactory.makeErrorMessage(seq, pydevd_tracing.GetExceptionTracebackStr())
783
784 elif cmd_id == CMD_ADD_DJANGO_EXCEPTION_BREAK:
785 exception = text
786
787 self.django_exception_break[exception] = True
788 self.setTracingForUntracedContexts()
789
790 elif cmd_id == CMD_REMOVE_DJANGO_EXCEPTION_BREAK:
791 exception = text
792
793 try:
794 del self.django_exception_break[exception]
795 except :
796 pass
797
798 else:
799 #I have no idea what this is all about
800 cmd = self.cmdFactory.makeErrorMessage(seq, "unexpected command " + str(cmd_id))
801
802 if cmd is not None:
803 self.writer.addCommand(cmd)
804 del cmd
805
806 except Exception:
807 traceback.print_exc()
808 cmd = self.cmdFactory.makeErrorMessage(seq,
809 "Unexpected exception in processNetCommand.\nInitial params: %s" % ((cmd_id, seq, text),))
810
811 self.writer.addCommand(cmd)
812 finally:
813 self._main_lock.release()
814
815 def processThreadNotAlive(self, threadId):
816 """ if thread is not alive, cancel trace_dispatch processing """
817 self._lock_running_thread_ids.acquire()
818 try:
819 thread = self._running_thread_ids.pop(threadId, None)
820 if thread is None:
821 return
822
823 wasNotified = thread.additionalInfo.pydev_notify_kill
824 if not wasNotified:
825 thread.additionalInfo.pydev_notify_kill = True
826
827 finally:
828 self._lock_running_thread_ids.release()
829
830 cmd = self.cmdFactory.makeThreadKilledMessage(threadId)
831 self.writer.addCommand(cmd)
832
833
834 def setSuspend(self, thread, stop_reason):
835 thread.additionalInfo.suspend_type = PYTHON_SUSPEND
836 thread.additionalInfo.pydev_state = STATE_SUSPEND
837 thread.stop_reason = stop_reason
838
839
840 def doWaitSuspend(self, thread, frame, event, arg): #@UnusedVariable
841 """ busy waits until the thread state changes to RUN
842 it expects thread's state as attributes of the thread.
843 Upon running, processes any outstanding Stepping commands.
844 """
845 self.processInternalCommands()
846
847 message = getattr(thread.additionalInfo, "message", None)
848
849 cmd = self.cmdFactory.makeThreadSuspendMessage(GetThreadId(thread), frame, thread.stop_reason, message)
850 self.writer.addCommand(cmd)
851
852 info = thread.additionalInfo
853
854 while info.pydev_state == STATE_SUSPEND and not self._finishDebuggingSession:
855 self.processInternalCommands()
856 time.sleep(0.01)
857
858 #process any stepping instructions
859 if info.pydev_step_cmd == CMD_STEP_INTO:
860 info.pydev_step_stop = None
861 info.pydev_smart_step_stop = None
862
863 elif info.pydev_step_cmd == CMD_STEP_OVER:
864 info.pydev_step_stop = frame
865 info.pydev_smart_step_stop = None
866 self.SetTraceForFrameAndParents(frame)
867
868 elif info.pydev_step_cmd == CMD_SMART_STEP_INTO:
869 self.SetTraceForFrameAndParents(frame)
870 info.pydev_step_stop = None
871 info.pydev_smart_step_stop = frame
872
873 elif info.pydev_step_cmd == CMD_RUN_TO_LINE or info.pydev_step_cmd == CMD_SET_NEXT_STATEMENT :
874 self.SetTraceForFrameAndParents(frame)
875
876 if event == 'line' or event == 'exception':
877 #If we're already in the correct context, we have to stop it now, because we can act only on
878 #line events -- if a return was the next statement it wouldn't work (so, we have this code
879 #repeated at pydevd_frame).
880 stop = False
881 curr_func_name = frame.f_code.co_name
882
883 #global context is set with an empty name
884 if curr_func_name in ('?', '<module>'):
885 curr_func_name = ''
886
887 if curr_func_name == info.pydev_func_name:
888 line = info.pydev_next_line
889 if frame.f_lineno == line:
890 stop = True
891 else :
892 if frame.f_trace is None:
893 frame.f_trace = self.trace_dispatch
894 frame.f_lineno = line
895 frame.f_trace = None
896 stop = True
897 if stop:
898 info.pydev_state = STATE_SUSPEND
899 self.doWaitSuspend(thread, frame, event, arg)
900 return
901
902
903 elif info.pydev_step_cmd == CMD_STEP_RETURN:
904 back_frame = frame.f_back
905 if back_frame is not None:
906 #steps back to the same frame (in a return call it will stop in the 'back frame' for the user)
907 info.pydev_step_stop = frame
908 self.SetTraceForFrameAndParents(frame)
909 else:
910 #No back frame?!? -- this happens in jython when we have some frame created from an awt event
911 #(the previous frame would be the awt event, but this doesn't make part of 'jython', only 'java')
912 #so, if we're doing a step return in this situation, it's the same as just making it run
913 info.pydev_step_stop = None
914 info.pydev_step_cmd = None
915 info.pydev_state = STATE_RUN
916
917 del frame
918 cmd = self.cmdFactory.makeThreadRunMessage(GetThreadId(thread), info.pydev_step_cmd)
919 self.writer.addCommand(cmd)
920
921
922 def handle_post_mortem_stop(self, additionalInfo, t):
923 pydev_log.debug("We are stopping in post-mortem\n")
924 self.force_post_mortem_stop -= 1
925 frame, frames_byid = additionalInfo.pydev_force_stop_at_exception
926 thread_id = GetThreadId(t)
927 pydevd_vars.addAdditionalFrameById(thread_id, frames_byid)
928 try:
929 try:
930 add_exception_to_frame(frame, additionalInfo.exception)
931 self.setSuspend(t, CMD_ADD_EXCEPTION_BREAK)
932 self.doWaitSuspend(t, frame, 'exception', None)
933 except:
934 pydev_log.error("We've got an error while stopping in post-mortem: %s\n"%sys.exc_info()[0])
935 finally:
936 additionalInfo.pydev_force_stop_at_exception = None
937 pydevd_vars.removeAdditionalFrameById(thread_id)
938
939 def trace_dispatch(self, frame, event, arg):
940 ''' This is the callback used when we enter some context in the debugger.
941
942 We also decorate the thread we are in with info about the debugging.
943 The attributes added are:
944 pydev_state
945 pydev_step_stop
946 pydev_step_cmd
947 pydev_notify_kill
948 '''
949 try:
950 if self._finishDebuggingSession and not self._terminationEventSent:
951 #that was not working very well because jython gave some socket errors
952 t = threadingCurrentThread()
953 try:
954 threads = threadingEnumerate()
955 for t in threads:
956 if hasattr(t, 'doKillPydevThread'):
957 t.doKillPydevThread()
958 except:
959 traceback.print_exc()
960 self._terminationEventSent = True
961 return None
962
963 filename, base = GetFilenameAndBase(frame)
964
965 is_file_to_ignore = DictContains(DONT_TRACE, base) #we don't want to debug threading or anything related to pydevd
966
967 if is_file_to_ignore:
968 return None
969
970 #print('trace_dispatch', base, frame.f_lineno, event, frame.f_code.co_name)
971 try:
972 #this shouldn't give an exception, but it could happen... (python bug)
973 #see http://mail.python.org/pipermail/python-bugs-list/2007-June/038796.html
974 #and related bug: http://bugs.python.org/issue1733757
975 t = threadingCurrentThread()
976 except:
977 frame.f_trace = self.trace_dispatch
978 return self.trace_dispatch
979
980 try:
981 additionalInfo = t.additionalInfo
982 if additionalInfo is None:
983 raise AttributeError()
984 except:
985 t.additionalInfo = PyDBAdditionalThreadInfo()
986 additionalInfo = t.additionalInfo
987
988 if additionalInfo is None:
989 return None
990
991 if additionalInfo.is_tracing:
992 f = frame
993 while f is not None:
994 fname, bs = GetFilenameAndBase(f)
995 if bs == 'pydevd_frame.py':
996 if 'trace_dispatch' == f.f_code.co_name:
997 return None #we don't wan't to trace code invoked from pydevd_frame.trace_dispatch
998 f = f.f_back
999
1000 # if thread is not alive, cancel trace_dispatch processing
Tor Norbye92584642014-04-17 08:39:25 -07001001 if not isThreadAlive(t):
Tor Norbye3a2425a2013-11-04 10:16:08 -08001002 self.processThreadNotAlive(GetThreadId(t))
Tor Norbye92584642014-04-17 08:39:25 -07001003 return None # suspend tracing
Tor Norbye3a2425a2013-11-04 10:16:08 -08001004
1005 if is_file_to_ignore:
1006 return None
1007
1008 #each new frame...
1009 return additionalInfo.CreateDbFrame((self, filename, additionalInfo, t, frame)).trace_dispatch(frame, event, arg)
1010
1011 except SystemExit:
1012 return None
1013
1014 except TypeError:
1015 return None
1016
1017 except Exception:
1018 #Log it
1019 if traceback is not None:
1020 #This can actually happen during the interpreter shutdown in Python 2.7
1021 traceback.print_exc()
1022 return None
1023
1024 if USE_PSYCO_OPTIMIZATION:
1025 try:
1026 import psyco
1027 trace_dispatch = psyco.proxy(trace_dispatch)
1028 processNetCommand = psyco.proxy(processNetCommand)
1029 processInternalCommands = psyco.proxy(processInternalCommands)
1030 doWaitSuspend = psyco.proxy(doWaitSuspend)
1031 getInternalQueue = psyco.proxy(getInternalQueue)
1032 except ImportError:
1033 if hasattr(sys, 'exc_clear'): #jython does not have it
1034 sys.exc_clear() #don't keep the traceback (let's keep it clear for when we go to the point of executing client code)
1035
1036 if not IS_PY3K and not IS_PY27 and not IS_64_BITS and not sys.platform.startswith("java") and not sys.platform.startswith("cli"):
1037 sys.stderr.write("pydev debugger: warning: psyco not available for speedups (the debugger will still work correctly, but a bit slower)\n")
1038 sys.stderr.flush()
1039
1040
1041
1042 def SetTraceForFrameAndParents(self, frame, also_add_to_passed_frame=True, overwrite_prev=False):
1043 dispatch_func = self.trace_dispatch
1044
1045 if also_add_to_passed_frame:
1046 self.update_trace(frame, dispatch_func, overwrite_prev)
1047
1048 frame = frame.f_back
1049 while frame:
1050 self.update_trace(frame, dispatch_func, overwrite_prev)
1051
1052 frame = frame.f_back
1053 del frame
1054
1055 def update_trace(self, frame, dispatch_func, overwrite_prev):
1056 if frame.f_trace is None:
1057 frame.f_trace = dispatch_func
1058 else:
1059 if overwrite_prev:
1060 frame.f_trace = dispatch_func
1061 else:
1062 try:
1063 #If it's the trace_exception, go back to the frame trace dispatch!
1064 if frame.f_trace.im_func.__name__ == 'trace_exception':
1065 frame.f_trace = frame.f_trace.im_self.trace_dispatch
1066 except AttributeError:
1067 pass
1068 frame = frame.f_back
1069 del frame
1070
1071
1072
1073 def run(self, file, globals=None, locals=None):
1074
1075 if globals is None:
1076 #patch provided by: Scott Schlesier - when script is run, it does not
1077 #use globals from pydevd:
1078 #This will prevent the pydevd script from contaminating the namespace for the script to be debugged
1079
1080 #pretend pydevd is not the main module, and
1081 #convince the file to be debugged that it was loaded as main
1082 sys.modules['pydevd'] = sys.modules['__main__']
1083 sys.modules['pydevd'].__name__ = 'pydevd'
1084
1085 from imp import new_module
1086 m = new_module('__main__')
1087 sys.modules['__main__'] = m
Tor Norbye70ae6f22014-02-06 14:02:54 -08001088 if hasattr(sys.modules['pydevd'], '__loader__'):
1089 setattr(m, '__loader__', getattr(sys.modules['pydevd'], '__loader__'))
1090
Tor Norbye3a2425a2013-11-04 10:16:08 -08001091 m.__file__ = file
1092 globals = m.__dict__
1093 try:
1094 globals['__builtins__'] = __builtins__
1095 except NameError:
1096 pass #Not there on Jython...
1097
1098 if locals is None:
1099 locals = globals
1100
1101 #Predefined (writable) attributes: __name__ is the module's name;
1102 #__doc__ is the module's documentation string, or None if unavailable;
1103 #__file__ is the pathname of the file from which the module was loaded,
1104 #if it was loaded from a file. The __file__ attribute is not present for
1105 #C modules that are statically linked into the interpreter; for extension modules
1106 #loaded dynamically from a shared library, it is the pathname of the shared library file.
1107
1108
1109 #I think this is an ugly hack, bug it works (seems to) for the bug that says that sys.path should be the same in
1110 #debug and run.
1111 if m.__file__.startswith(sys.path[0]):
1112 #print >> sys.stderr, 'Deleting: ', sys.path[0]
1113 del sys.path[0]
1114
1115 #now, the local directory has to be added to the pythonpath
1116 #sys.path.insert(0, os.getcwd())
1117 #Changed: it's not the local directory, but the directory of the file launched
1118 #The file being run ust be in the pythonpath (even if it was not before)
1119 sys.path.insert(0, os.path.split(file)[0])
1120
1121 # for completness, we'll register the pydevd.reader & pydevd.writer threads
1122 net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.reader" id="-1"/></xml>')
1123 self.writer.addCommand(net)
1124 net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.writer" id="-1"/></xml>')
1125 self.writer.addCommand(net)
1126
1127 pydevd_tracing.SetTrace(self.trace_dispatch)
1128 try:
1129 #not available in jython!
1130 threading.settrace(self.trace_dispatch) # for all future threads
1131 except:
1132 pass
1133
1134 try:
1135 thread.start_new_thread = pydev_start_new_thread
1136 thread.start_new = pydev_start_new_thread
1137 except:
1138 pass
1139
1140 while not self.readyToRun:
1141 time.sleep(0.1) # busy wait until we receive run command
1142
1143 PyDBCommandThread(debugger).start()
1144 PyDBCheckAliveThread(debugger).start()
1145
1146 if pydevd_vm_type.GetVmType() == pydevd_vm_type.PydevdVmType.JYTHON and sys.version_info[1] == 5 and sys.version_info[2] >= 3:
1147 from _pydev_jython_execfile import jython_execfile
1148 jython_execfile(sys.argv)
1149 else:
1150 pydev_imports.execfile(file, globals, locals) #execute the script
1151
1152 def exiting(self):
1153 sys.stdout.flush()
1154 sys.stderr.flush()
1155 self.checkOutputRedirect()
1156 cmd = self.cmdFactory.makeExitMessage()
1157 self.writer.addCommand(cmd)
1158
1159def set_debug(setup):
1160 setup['DEBUG_RECORD_SOCKET_READS'] = True
1161 setup['DEBUG_TRACE_BREAKPOINTS'] = 1
1162 setup['DEBUG_TRACE_LEVEL'] = 3
1163
1164
1165def processCommandLine(argv):
1166 """ parses the arguments.
1167 removes our arguments from the command line """
1168 setup = {}
1169 setup['client'] = ''
1170 setup['server'] = False
1171 setup['port'] = 0
1172 setup['file'] = ''
1173 setup['multiproc'] = False
1174 setup['save-signatures'] = False
1175 i = 0
1176 del argv[0]
1177 while (i < len(argv)):
1178 if (argv[i] == '--port'):
1179 del argv[i]
1180 setup['port'] = int(argv[i])
1181 del argv[i]
1182 elif (argv[i] == '--vm_type'):
1183 del argv[i]
1184 setup['vm_type'] = argv[i]
1185 del argv[i]
1186 elif (argv[i] == '--client'):
1187 del argv[i]
1188 setup['client'] = argv[i]
1189 del argv[i]
1190 elif (argv[i] == '--server'):
1191 del argv[i]
1192 setup['server'] = True
1193 elif (argv[i] == '--file'):
1194 del argv[i]
1195 setup['file'] = argv[i]
1196 i = len(argv) # pop out, file is our last argument
1197 elif (argv[i] == '--DEBUG_RECORD_SOCKET_READS'):
1198 del argv[i]
1199 setup['DEBUG_RECORD_SOCKET_READS'] = True
1200 elif (argv[i] == '--DEBUG'):
1201 del argv[i]
1202 set_debug(setup)
1203 elif (argv[i] == '--multiproc'):
1204 del argv[i]
1205 setup['multiproc'] = True
1206 elif (argv[i] == '--save-signatures'):
1207 del argv[i]
1208 setup['save-signatures'] = True
1209 else:
1210 raise ValueError("unexpected option " + argv[i])
1211 return setup
1212
1213def usage(doExit=0):
1214 sys.stdout.write('Usage:\n')
1215 sys.stdout.write('pydevd.py --port=N [(--client hostname) | --server] --file executable [file_options]\n')
1216 if doExit:
1217 sys.exit(0)
1218
1219def SetTraceForParents(frame, dispatch_func):
1220 frame = frame.f_back
1221 while frame:
1222 if frame.f_trace is None:
1223 frame.f_trace = dispatch_func
1224
1225 frame = frame.f_back
1226 del frame
1227
1228def exit_hook():
1229 debugger = GetGlobalDebugger()
1230 debugger.exiting()
1231
1232def initStdoutRedirect():
1233 if not getattr(sys, 'stdoutBuf', None):
1234 sys.stdoutBuf = pydevd_io.IOBuf()
1235 sys.stdout = pydevd_io.IORedirector(sys.stdout, sys.stdoutBuf) #@UndefinedVariable
1236
1237def initStderrRedirect():
1238 if not getattr(sys, 'stderrBuf', None):
1239 sys.stderrBuf = pydevd_io.IOBuf()
1240 sys.stderr = pydevd_io.IORedirector(sys.stderr, sys.stderrBuf) #@UndefinedVariable
1241
1242def settrace(host='localhost', stdoutToServer=False, stderrToServer=False, port=5678, suspend=True, trace_only_current_thread=False, overwrite_prev_trace=False):
1243 '''Sets the tracing function with the pydev debug function and initializes needed facilities.
1244
1245 @param host: the user may specify another host, if the debug server is not in the same machine
1246 @param stdoutToServer: when this is true, the stdout is passed to the debug server
1247 @param stderrToServer: when this is true, the stderr is passed to the debug server
1248 so that they are printed in its console and not in this process console.
1249 @param port: specifies which port to use for communicating with the server (note that the server must be started
1250 in the same port). @note: currently it's hard-coded at 5678 in the client
1251 @param suspend: whether a breakpoint should be emulated as soon as this function is called.
1252 @param trace_only_current_thread: determines if only the current thread will be traced or all future threads will also have the tracing enabled.
1253 '''
1254 _set_trace_lock.acquire()
1255 try:
1256 _locked_settrace(host, stdoutToServer, stderrToServer, port, suspend, trace_only_current_thread, overwrite_prev_trace)
1257 finally:
1258 _set_trace_lock.release()
1259
1260_set_trace_lock = threading.Lock()
1261
1262def _locked_settrace(host, stdoutToServer, stderrToServer, port, suspend, trace_only_current_thread, overwrite_prev_trace):
1263 if host is None:
1264 import pydev_localhost
1265 host = pydev_localhost.get_localhost()
1266
1267 global connected
1268 global bufferStdOutToServer
1269 global bufferStdErrToServer
1270 global remote
1271
1272 remote = True
1273
1274 if not connected :
1275 connected = True
1276 bufferStdOutToServer = stdoutToServer
1277 bufferStdErrToServer = stderrToServer
1278
1279 pydevd_vm_type.SetupType()
1280
1281 debugger = PyDB()
1282 debugger.connect(host, port)
1283
1284 net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.reader" id="-1"/></xml>')
1285 debugger.writer.addCommand(net)
1286 net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.writer" id="-1"/></xml>')
1287 debugger.writer.addCommand(net)
1288
1289 if bufferStdOutToServer:
1290 initStdoutRedirect()
1291
1292 if bufferStdErrToServer:
1293 initStderrRedirect()
1294
1295 debugger.SetTraceForFrameAndParents(GetFrame(), False, overwrite_prev=overwrite_prev_trace)
1296
1297 t = threadingCurrentThread()
1298 try:
1299 additionalInfo = t.additionalInfo
1300 except AttributeError:
1301 additionalInfo = PyDBAdditionalThreadInfo()
1302 t.additionalInfo = additionalInfo
1303
1304 while not debugger.readyToRun:
1305 time.sleep(0.1) # busy wait until we receive run command
1306
1307 if suspend:
1308 debugger.setSuspend(t, CMD_SET_BREAK)
1309
1310 #note that we do that through pydevd_tracing.SetTrace so that the tracing
1311 #is not warned to the user!
1312 pydevd_tracing.SetTrace(debugger.trace_dispatch)
1313
1314 if not trace_only_current_thread:
1315 #Trace future threads?
1316 try:
1317 #not available in jython!
1318 threading.settrace(debugger.trace_dispatch) # for all future threads
1319 except:
1320 pass
1321
1322 try:
1323 thread.start_new_thread = pydev_start_new_thread
1324 thread.start_new = pydev_start_new_thread
1325 except:
1326 pass
1327
1328 sys.exitfunc = exit_hook
1329
1330 PyDBCommandThread(debugger).start()
1331 PyDBCheckAliveThread(debugger).start()
1332
1333 else:
1334 #ok, we're already in debug mode, with all set, so, let's just set the break
1335 debugger = GetGlobalDebugger()
1336
1337 debugger.SetTraceForFrameAndParents(GetFrame(), False)
1338
1339 t = threadingCurrentThread()
1340 try:
1341 additionalInfo = t.additionalInfo
1342 except AttributeError:
1343 additionalInfo = PyDBAdditionalThreadInfo()
1344 t.additionalInfo = additionalInfo
1345
1346 pydevd_tracing.SetTrace(debugger.trace_dispatch)
1347
1348 if not trace_only_current_thread:
1349 #Trace future threads?
1350 try:
1351 #not available in jython!
1352 threading.settrace(debugger.trace_dispatch) # for all future threads
1353 except:
1354 pass
1355
1356 try:
1357 thread.start_new_thread = pydev_start_new_thread
1358 thread.start_new = pydev_start_new_thread
1359 except:
1360 pass
1361
1362 if suspend:
1363 debugger.setSuspend(t, CMD_SET_BREAK)
1364
1365def stoptrace():
1366 global connected
1367 if connected:
1368 pydevd_tracing.RestoreSysSetTraceFunc()
1369 sys.settrace(None)
1370 try:
1371 #not available in jython!
1372 threading.settrace(None) # for all future threads
1373 except:
1374 pass
1375
1376 try:
1377 thread.start_new_thread = _original_start_new_thread
1378 thread.start_new = _original_start_new_thread
1379 except:
1380 pass
1381
1382 debugger = GetGlobalDebugger()
1383
1384 if debugger:
1385 debugger.trace_dispatch = None
1386
1387 debugger.SetTraceForFrameAndParents(GetFrame(), False)
1388
1389 debugger.exiting()
1390
1391 killAllPydevThreads()
1392
1393 connected = False
1394
1395class Dispatcher(object):
1396 def __init__(self):
1397 self.port = None
1398
1399 def connect(self, host, port):
1400 self.host = host
1401 self.port = port
1402 self.client = StartClient(self.host, self.port)
1403 self.reader = DispatchReader(self)
1404 self.reader.dontTraceMe = False #we run reader in the same thread so we don't want to loose tracing
1405 self.reader.run()
1406
1407 def close(self):
1408 try:
1409 self.reader.doKillPydevThread()
1410 except :
1411 pass
1412
1413class DispatchReader(ReaderThread):
1414 def __init__(self, dispatcher):
1415 self.dispatcher = dispatcher
1416 ReaderThread.__init__(self, self.dispatcher.client)
1417
1418 def handleExcept(self):
1419 ReaderThread.handleExcept(self)
1420
1421 def processCommand(self, cmd_id, seq, text):
1422 if cmd_id == 99:
1423 self.dispatcher.port = int(text)
1424 self.killReceived = True
1425
1426
1427def dispatch():
1428 argv = sys.original_argv[:]
1429 setup = processCommandLine(argv)
1430 host = setup['client']
1431 port = setup['port']
1432 dispatcher = Dispatcher()
1433 try:
1434 dispatcher.connect(host, port)
1435 port = dispatcher.port
1436 finally:
1437 dispatcher.close()
1438 return host, port
1439
1440
1441def settrace_forked():
1442 host, port = dispatch()
1443
1444 import pydevd_tracing
1445 pydevd_tracing.RestoreSysSetTraceFunc()
1446
1447 if port is not None:
1448 global connected
1449 connected = False
1450 settrace(host, port=port, suspend=False, overwrite_prev_trace=True)
1451#=======================================================================================================================
1452# main
1453#=======================================================================================================================
1454if __name__ == '__main__':
1455 # parse the command line. --file is our last argument that is required
1456 try:
1457 sys.original_argv = sys.argv[:]
1458 setup = processCommandLine(sys.argv)
1459 except ValueError:
1460 traceback.print_exc()
1461 usage(1)
1462
1463
1464 #as to get here all our imports are already resolved, the psyco module can be
1465 #changed and we'll still get the speedups in the debugger, as those functions
1466 #are already compiled at this time.
1467 try:
1468 import psyco
1469 except ImportError:
1470 if hasattr(sys, 'exc_clear'): #jython does not have it
1471 sys.exc_clear() #don't keep the traceback -- clients don't want to see it
1472 pass #that's ok, no need to mock psyco if it's not available anyways
1473 else:
1474 #if it's available, let's change it for a stub (pydev already made use of it)
1475 import pydevd_psyco_stub
1476 sys.modules['psyco'] = pydevd_psyco_stub
1477
1478 fix_getpass.fixGetpass()
1479
1480
1481 pydev_log.debug("Executing file %s" % setup['file'])
1482 pydev_log.debug("arguments: %s"% str(sys.argv))
1483
1484
1485 pydevd_vm_type.SetupType(setup.get('vm_type', None))
1486
1487 if os.getenv('PYCHARM_DEBUG'):
1488 set_debug(setup)
1489
1490 DebugInfoHolder.DEBUG_RECORD_SOCKET_READS = setup.get('DEBUG_RECORD_SOCKET_READS', False)
1491 DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS = setup.get('DEBUG_TRACE_BREAKPOINTS', -1)
1492 DebugInfoHolder.DEBUG_TRACE_LEVEL = setup.get('DEBUG_TRACE_LEVEL', -1)
1493
1494 port = setup['port']
1495 host = setup['client']
1496
1497 if setup['multiproc']:
1498 pydev_log.debug("Started in multiproc mode\n")
1499
1500 dispatcher = Dispatcher()
1501 try:
1502 dispatcher.connect(host, port)
1503 if dispatcher.port is not None:
1504 port = dispatcher.port
1505 pydev_log.debug("Received port %d\n" %port)
1506 pydev_log.info("pydev debugger: process %d is connecting\n"% os.getpid())
1507
1508 try:
1509 pydev_monkey.patch_new_process_functions()
1510 except:
1511 pydev_log.error("Error patching process functions\n")
1512 traceback.print_exc()
1513 else:
1514 pydev_log.error("pydev debugger: couldn't get port for new debug process\n")
1515 finally:
1516 dispatcher.close()
1517 else:
1518 pydev_log.info("pydev debugger: starting\n")
1519
1520 try:
1521 pydev_monkey.patch_new_process_functions_with_warning()
1522 except:
1523 pydev_log.error("Error patching process functions\n")
1524 traceback.print_exc()
1525
1526
1527 debugger = PyDB()
1528
1529 if setup['save-signatures']:
1530 if pydevd_vm_type.GetVmType() == pydevd_vm_type.PydevdVmType.JYTHON:
1531 sys.stderr.write("Collecting run-time type information is not supported for Jython\n")
1532 else:
1533 debugger.signature_factory = SignatureFactory()
1534
1535 debugger.connect(host, port)
1536
1537 connected = True #Mark that we're connected when started from inside ide.
1538
1539 debugger.run(setup['file'], None, None)