Merge remote-tracking branch 'origin/master'
[idea/community.git] / python / helpers / pydev / pydevd.py
1 #IMPORTANT: pydevd_constants must be the 1st thing defined because it'll keep a reference to the original sys._getframe
2 from __future__ import nested_scopes # Jython 2.1 support
3 from pydevd_constants import * # @UnusedWildImport
4
5 import pydev_monkey_qt
6 from pydevd_utils import save_main_module
7
8 pydev_monkey_qt.patch_qt()
9
10 import traceback
11
12 from pydevd_frame_utils import add_exception_to_frame
13 import pydev_imports
14 from pydevd_breakpoints import * #@UnusedWildImport
15 import fix_getpass
16 from pydevd_comm import  CMD_CHANGE_VARIABLE, \
17                          CMD_EVALUATE_EXPRESSION, \
18                          CMD_EXEC_EXPRESSION, \
19                          CMD_GET_COMPLETIONS, \
20                          CMD_GET_FRAME, \
21                          CMD_GET_VARIABLE, \
22                          CMD_GET_ARRAY, \
23                          CMD_LIST_THREADS, \
24                          CMD_REMOVE_BREAK, \
25                          CMD_RUN, \
26                          CMD_SET_BREAK, \
27                          CMD_SET_NEXT_STATEMENT,\
28                          CMD_STEP_INTO, \
29                          CMD_STEP_OVER, \
30                          CMD_STEP_RETURN, \
31                          CMD_THREAD_CREATE, \
32                          CMD_THREAD_KILL, \
33                          CMD_THREAD_RUN, \
34                          CMD_THREAD_SUSPEND, \
35                          CMD_RUN_TO_LINE, \
36                          CMD_RELOAD_CODE, \
37                          CMD_VERSION, \
38                          CMD_CONSOLE_EXEC, \
39                          CMD_ADD_EXCEPTION_BREAK, \
40                          CMD_REMOVE_EXCEPTION_BREAK, \
41                          CMD_LOAD_SOURCE, \
42                          CMD_ADD_DJANGO_EXCEPTION_BREAK, \
43                          CMD_REMOVE_DJANGO_EXCEPTION_BREAK, \
44                          CMD_SMART_STEP_INTO,\
45                          InternalChangeVariable, \
46                          InternalGetCompletions, \
47                          InternalEvaluateExpression, \
48                          InternalConsoleExec, \
49                          InternalGetFrame, \
50                          InternalGetVariable, \
51                          InternalGetArray, \
52                          InternalTerminateThread, \
53                          InternalRunThread, \
54                          InternalStepThread, \
55                          NetCommand, \
56                          NetCommandFactory, \
57                          PyDBDaemonThread, \
58                          _queue, \
59                          ReaderThread, \
60                          SetGlobalDebugger, \
61                          WriterThread, \
62                          PydevdFindThreadById, \
63                          PydevdLog, \
64                          StartClient, \
65                          StartServer, \
66                          InternalSetNextStatementThread, \
67                          ReloadCodeCommand, \
68                          ID_TO_MEANING,\
69                          CMD_SET_PY_EXCEPTION, \
70                          CMD_IGNORE_THROWN_EXCEPTION_AT,\
71                          InternalGetBreakpointException, \
72                          InternalSendCurrExceptionTrace,\
73                          InternalSendCurrExceptionTraceProceeded,\
74                          CMD_ENABLE_DONT_TRACE, \
75                          CMD_GET_FILE_CONTENTS,\
76                          CMD_SET_PROPERTY_TRACE, CMD_RUN_CUSTOM_OPERATION,\
77                          InternalRunCustomOperation, CMD_EVALUATE_CONSOLE_EXPRESSION, InternalEvaluateConsoleExpression,\
78                          InternalConsoleGetCompletions
79
80 from pydevd_file_utils import NormFileToServer, GetFilenameAndBase
81 import pydevd_file_utils
82 import pydevd_vars
83 import pydevd_vm_type
84 import pydevd_tracing
85 import pydevd_io
86 from pydevd_additional_thread_info import PyDBAdditionalThreadInfo
87 from pydevd_custom_frames import CustomFramesContainer, CustomFramesContainerInit
88 import pydevd_dont_trace
89 import pydevd_traceproperty
90
91 from _pydev_imps import _pydev_time as time, _pydev_thread
92
93 import _pydev_threading as threading
94
95 import os
96 import atexit
97
98 SUPPORT_PLUGINS = not IS_JYTH_LESS25
99 PluginManager = None
100 if SUPPORT_PLUGINS:
101     from pydevd_plugin_utils import PluginManager
102
103 threadingEnumerate = threading.enumerate
104 threadingCurrentThread = threading.currentThread
105
106 try:
107     'dummy'.encode('utf-8') # Added because otherwise Jython 2.2.1 wasn't finding the encoding (if it wasn't loaded in the main thread).
108 except:
109     pass
110
111 DONT_TRACE = {
112               # commonly used things from the stdlib that we don't want to trace
113               'Queue.py':1,
114               'queue.py':1,
115               'socket.py':1,
116               'weakref.py':1,
117               '_weakrefset.py':1,
118               'linecache.py':1,
119               'threading.py':1,
120
121               # thirs party libs that we don't want to trace
122               '_pydev_pluginbase.py':1,
123               '_pydev_pkgutil_old.py':1,
124               '_pydev_uuid_old.py':1,
125
126               #things from pydev that we don't want to trace
127               '_pydev_execfile.py':1,
128               '_pydev_jython_execfile.py':1,
129               '_pydev_threading':1,
130               '_pydev_Queue':1,
131               'django_debug.py':1,
132               'jinja2_debug.py':1,
133               'pydev_log.py':1,
134               'pydev_monkey.py':1 ,
135               'pydev_monkey_qt.py':1 ,
136               'pydevd.py':1 ,
137               'pydevd_additional_thread_info.py':1,
138               'pydevd_comm.py':1,
139               'pydevd_console.py':1 ,
140               'pydevd_constants.py':1,
141               'pydevd_custom_frames.py':1,
142               'pydevd_dont_trace.py':1,
143               'pydevd_exec.py':1,
144               'pydevd_exec2.py':1,
145               'pydevd_file_utils.py':1,
146               'pydevd_frame.py':1,
147               'pydevd_import_class.py':1 ,
148               'pydevd_io.py':1 ,
149               'pydevd_psyco_stub.py':1,
150               'pydevd_referrers.py':1 ,
151               'pydevd_reload.py':1 ,
152               'pydevd_resolver.py':1 ,
153               'pydevd_save_locals.py':1 ,
154               'pydevd_signature.py':1,
155               'pydevd_stackless.py':1 ,
156               'pydevd_traceproperty.py':1,
157               'pydevd_tracing.py':1 ,
158               'pydevd_utils.py':1,
159               'pydevd_vars.py':1,
160               'pydevd_vm_type.py':1,
161               'pydevd_xml.py':1,
162             }
163
164 if IS_PY3K:
165     # if we try to trace io.py it seems it can get halted (see http://bugs.python.org/issue4716)
166     DONT_TRACE['io.py'] = 1
167
168     # Don't trace common encodings too
169     DONT_TRACE['cp1252.py'] = 1
170     DONT_TRACE['utf_8.py'] = 1
171
172
173 connected = False
174 bufferStdOutToServer = False
175 bufferStdErrToServer = False
176 remote = False
177
178 from _pydev_filesystem_encoding import getfilesystemencoding
179 file_system_encoding = getfilesystemencoding()
180
181
182 # Hack for https://sw-brainwy.rhcloud.com/tracker/PyDev/363 (i.e.: calling isAlive() can throw AssertionError under some circumstances)
183 # It is required to debug threads started by start_new_thread in Python 3.4
184 _temp = threading.Thread()
185 if hasattr(_temp, '_is_stopped'): # Python 3.4 has this
186     def isThreadAlive(t):
187         try:
188             return not t._is_stopped
189         except:
190             return t.isAlive()
191     
192 elif hasattr(_temp, '_Thread__stopped'): # Python 2.7 has this
193     def isThreadAlive(t):
194         try:
195             return not t._Thread__stopped
196         except:
197             return t.isAlive()
198     
199 else: # Haven't checked all other versions, so, let's use the regular isAlive call in this case.
200     def isThreadAlive(t):
201         return t.isAlive()
202 del _temp
203
204 #=======================================================================================================================
205 # PyDBCommandThread
206 #=======================================================================================================================
207 class PyDBCommandThread(PyDBDaemonThread):
208
209     def __init__(self, pyDb):
210         PyDBDaemonThread.__init__(self)
211         self._py_db_command_thread_event = pyDb._py_db_command_thread_event
212         self.pyDb = pyDb
213         self.setName('pydevd.CommandThread')
214
215     def OnRun(self):
216         for i in xrange(1, 10):
217             time.sleep(0.5) #this one will only start later on (because otherwise we may not have any non-daemon threads
218             if self.killReceived:
219                 return
220
221         if self.dontTraceMe:
222             self.pyDb.SetTrace(None) # no debugging on this thread
223
224         try:
225             while not self.killReceived:
226                 try:
227                     self.pyDb.processInternalCommands()
228                 except:
229                     PydevdLog(0, 'Finishing debug communication...(2)')
230                 self._py_db_command_thread_event.clear()
231                 self._py_db_command_thread_event.wait(0.5)
232         except:
233             pydev_log.debug(sys.exc_info()[0])
234
235             #only got this error in interpreter shutdown
236             #PydevdLog(0, 'Finishing debug communication...(3)')
237
238
239 def killAllPydevThreads():
240     threads = DictKeys(PyDBDaemonThread.created_pydb_daemon_threads)
241     for t in threads:
242         if hasattr(t, 'doKillPydevThread'):
243             t.doKillPydevThread()
244
245
246 #=======================================================================================================================
247 # CheckOutputThread
248 # Non-daemonic thread guaranties that all data is written even if program is finished
249 #=======================================================================================================================
250 class CheckOutputThread(PyDBDaemonThread):
251
252     def __init__(self, pyDb):
253         PyDBDaemonThread.__init__(self)
254         self.pyDb = pyDb
255         self.setName('pydevd.CheckAliveThread')
256         pyDb.output_checker = self
257
258     def start(self):
259         # it should be non daemon
260         thread = threading.Thread(target=self.run)
261         thread.daemon = False
262         thread.start()
263
264     def OnRun(self):
265             if self.dontTraceMe:
266
267                 disable_tracing = True
268         
269                 if pydevd_vm_type.GetVmType() == pydevd_vm_type.PydevdVmType.JYTHON and sys.hexversion <= 0x020201f0:
270                     # don't run untraced threads if we're in jython 2.2.1 or lower
271                     # jython bug: if we start a thread and another thread changes the tracing facility
272                     # it affects other threads (it's not set only for the thread but globally)
273                     # Bug: http://sourceforge.net/tracker/index.php?func=detail&aid=1870039&group_id=12867&atid=112867
274                     disable_tracing = False
275         
276                 if disable_tracing:
277                     pydevd_tracing.SetTrace(None)  # no debugging on this thread
278                     
279             while not self.killReceived:
280                 if not self.pyDb.haveAliveThreads() and self.pyDb.writer.empty() \
281                         and not has_data_to_redirect():
282                     try:
283                         pydev_log.debug("No alive threads, finishing debug session")
284                         self.pyDb.FinishDebuggingSession()
285                         killAllPydevThreads()
286                     except:
287                         traceback.print_exc()
288
289                     self.killReceived = True
290
291                 self.pyDb.checkOutputRedirect()
292
293                 time.sleep(0.3)
294
295     def doKillPydevThread(self):
296         self.killReceived = True
297
298
299
300 #=======================================================================================================================
301 # PyDB
302 #=======================================================================================================================
303 class PyDB:
304     """ Main debugging class
305     Lots of stuff going on here:
306
307     PyDB starts two threads on startup that connect to remote debugger (RDB)
308     The threads continuously read & write commands to RDB.
309     PyDB communicates with these threads through command queues.
310        Every RDB command is processed by calling processNetCommand.
311        Every PyDB net command is sent to the net by posting NetCommand to WriterThread queue
312
313        Some commands need to be executed on the right thread (suspend/resume & friends)
314        These are placed on the internal command queue.
315     """
316
317
318     def __init__(self):
319         SetGlobalDebugger(self)
320         pydevd_tracing.ReplaceSysSetTraceFunc()
321         self.reader = None
322         self.writer = None
323         self.output_checker = None
324         self.quitting = None
325         self.cmdFactory = NetCommandFactory()
326         self._cmd_queue = {}  # the hash of Queues. Key is thread id, value is thread
327
328         self.breakpoints = {}
329
330         self.file_to_id_to_line_breakpoint = {}
331         self.file_to_id_to_plugin_breakpoint = {}
332
333         # Note: breakpoints dict should not be mutated: a copy should be created
334         # and later it should be assigned back (to prevent concurrency issues).
335         self.break_on_uncaught_exceptions = {}
336         self.break_on_caught_exceptions = {}
337
338         self.readyToRun = False
339         self._main_lock = _pydev_thread.allocate_lock()
340         self._lock_running_thread_ids = _pydev_thread.allocate_lock()
341         self._py_db_command_thread_event = threading.Event()
342         CustomFramesContainer._py_db_command_thread_event = self._py_db_command_thread_event
343         self._finishDebuggingSession = False
344         self._terminationEventSent = False
345         self.signature_factory = None
346         self.SetTrace = pydevd_tracing.SetTrace
347         self.break_on_exceptions_thrown_in_same_context = False
348         self.ignore_exceptions_thrown_in_lines_with_ignore_exception = True
349
350         # Suspend debugger even if breakpoint condition raises an exception
351         SUSPEND_ON_BREAKPOINT_EXCEPTION = True
352         self.suspend_on_breakpoint_exception = SUSPEND_ON_BREAKPOINT_EXCEPTION
353
354         # By default user can step into properties getter/setter/deleter methods
355         self.disable_property_trace = False
356         self.disable_property_getter_trace = False
357         self.disable_property_setter_trace = False
358         self.disable_property_deleter_trace = False
359
360         #this is a dict of thread ids pointing to thread ids. Whenever a command is passed to the java end that
361         #acknowledges that a thread was created, the thread id should be passed here -- and if at some time we do not
362         #find that thread alive anymore, we must remove it from this list and make the java side know that the thread
363         #was killed.
364         self._running_thread_ids = {}
365         self._set_breakpoints_with_id = False
366
367         # This attribute holds the file-> lines which have an @IgnoreException.
368         self.filename_to_lines_where_exceptions_are_ignored = {}
369
370         #working with plugins (lazily initialized)
371         self.plugin = None
372         self.has_plugin_line_breaks = False
373         self.has_plugin_exception_breaks = False
374         
375     def get_plugin_lazy_init(self):
376         if self.plugin is None and SUPPORT_PLUGINS:
377             self.plugin = PluginManager(self)
378         return self.plugin
379
380
381     def haveAliveThreads(self):
382         for t in threadingEnumerate():
383             if isinstance(t, PyDBDaemonThread):
384                 pydev_log.error_once(
385                     'Error in debugger: Found PyDBDaemonThread through threading.enumerate().\n')
386                 
387             if getattr(t, 'is_pydev_daemon_thread', False):
388                 #Important: Jython 2.5rc4 has a bug where a thread created with thread.start_new_thread won't be
389                 #set as a daemon thread, so, we also have to check for the 'is_pydev_daemon_thread' flag.
390                 #See: https://github.com/fabioz/PyDev.Debugger/issues/11
391                 continue
392             
393             if isThreadAlive(t) and not t.isDaemon():
394                 return True
395
396         return False
397
398     def FinishDebuggingSession(self):
399         self._finishDebuggingSession = True
400
401     def acquire(self):
402         if PyDBUseLocks:
403             self.lock.acquire()
404         return True
405
406     def release(self):
407         if PyDBUseLocks:
408             self.lock.release()
409         return True
410
411     def initializeNetwork(self, sock):
412         try:
413             sock.settimeout(None)  # infinite, no timeouts from now on - jython does not have it
414         except:
415             pass
416         self.writer = WriterThread(sock)
417         self.reader = ReaderThread(sock)
418         self.writer.start()
419         self.reader.start()
420
421         time.sleep(0.1)  # give threads time to start
422
423     def connect(self, host, port):
424         if host:
425             s = StartClient(host, port)
426         else:
427             s = StartServer(port)
428
429         self.initializeNetwork(s)
430
431
432     def getInternalQueue(self, thread_id):
433         """ returns internal command queue for a given thread.
434         if new queue is created, notify the RDB about it """
435         if thread_id.startswith('__frame__'):
436             thread_id = thread_id[thread_id.rfind('|') + 1:]
437         try:
438             return self._cmd_queue[thread_id]
439         except KeyError:
440             return self._cmd_queue.setdefault(thread_id, _queue.Queue()) #@UndefinedVariable
441
442
443     def postInternalCommand(self, int_cmd, thread_id):
444         """ if thread_id is *, post to all """
445         if thread_id == "*":
446             threads = threadingEnumerate()
447             for t in threads:
448                 thread_id = GetThreadId(t)
449                 queue = self.getInternalQueue(thread_id)
450                 queue.put(int_cmd)
451
452         else:
453             queue = self.getInternalQueue(thread_id)
454             queue.put(int_cmd)
455
456     def checkOutputRedirect(self):
457         global bufferStdOutToServer
458         global bufferStdErrToServer
459
460         if bufferStdOutToServer:
461             initStdoutRedirect()
462             self.checkOutput(sys.stdoutBuf, 1) #@UndefinedVariable
463
464         if bufferStdErrToServer:
465             initStderrRedirect()
466             self.checkOutput(sys.stderrBuf, 2) #@UndefinedVariable
467
468     def checkOutput(self, out, outCtx):
469         '''Checks the output to see if we have to send some buffered output to the debug server
470
471         @param out: sys.stdout or sys.stderr
472         @param outCtx: the context indicating: 1=stdout and 2=stderr (to know the colors to write it)
473         '''
474
475         try:
476             v = out.getvalue()
477
478             if v:
479                 self.cmdFactory.makeIoMessage(v, outCtx, self)
480         except:
481             traceback.print_exc()
482
483
484     def processInternalCommands(self):
485         '''This function processes internal commands
486         '''
487         self._main_lock.acquire()
488         try:
489
490             self.checkOutputRedirect()
491
492             curr_thread_id = GetThreadId(threadingCurrentThread())
493             program_threads_alive = {}
494             all_threads = threadingEnumerate()
495             program_threads_dead = []
496             self._lock_running_thread_ids.acquire()
497             try:
498                 for t in all_threads:
499                     thread_id = GetThreadId(t)
500
501                     if isinstance(t, PyDBDaemonThread):
502                         pydev_log.error_once('Found PyDBDaemonThread in threading.enumerate.')
503                         
504                     elif getattr(t, 'is_pydev_daemon_thread', False):
505                         pass # I.e.: skip the DummyThreads created from pydev daemon threads
506                         
507                     elif isThreadAlive(t):
508                         program_threads_alive[thread_id] = t
509
510                         if not DictContains(self._running_thread_ids, thread_id):
511                             if not hasattr(t, 'additionalInfo'):
512                                 # see http://sourceforge.net/tracker/index.php?func=detail&aid=1955428&group_id=85796&atid=577329
513                                 # Let's create the additional info right away!
514                                 t.additionalInfo = PyDBAdditionalThreadInfo()
515                             self._running_thread_ids[thread_id] = t
516                             self.writer.addCommand(self.cmdFactory.makeThreadCreatedMessage(t))
517
518
519                         queue = self.getInternalQueue(thread_id)
520                         cmdsToReadd = []  # some commands must be processed by the thread itself... if that's the case,
521                                             # we will re-add the commands to the queue after executing.
522                         try:
523                             while True:
524                                 int_cmd = queue.get(False)
525                                 if int_cmd.canBeExecutedBy(curr_thread_id):
526                                     PydevdLog(2, "processing internal command ", str(int_cmd))
527                                     int_cmd.doIt(self)
528                                 else:
529                                     PydevdLog(2, "NOT processing internal command ", str(int_cmd))
530                                     cmdsToReadd.append(int_cmd)
531
532                         except _queue.Empty: #@UndefinedVariable
533                             for int_cmd in cmdsToReadd:
534                                 queue.put(int_cmd)
535                             # this is how we exit
536
537
538                 thread_ids = list(self._running_thread_ids.keys())
539                 for tId in thread_ids:
540                     if not DictContains(program_threads_alive, tId):
541                         program_threads_dead.append(tId)
542             finally:
543                 self._lock_running_thread_ids.release()
544
545             for tId in program_threads_dead:
546                 try:
547                     self.processThreadNotAlive(tId)
548                 except:
549                     sys.stderr.write('Error iterating through %s (%s) - %s\n' % (
550                         program_threads_alive, program_threads_alive.__class__, dir(program_threads_alive)))
551                     raise
552
553
554             if len(program_threads_alive) == 0:
555                 self.FinishDebuggingSession()
556                 for t in all_threads:
557                     if hasattr(t, 'doKillPydevThread'):
558                         t.doKillPydevThread()
559
560         finally:
561             self._main_lock.release()
562
563
564     def setTracingForUntracedContexts(self, ignore_frame=None, overwrite_prev_trace=False):
565         # Enable the tracing for existing threads (because there may be frames being executed that
566         # are currently untraced).
567         threads = threadingEnumerate()
568         try:
569             for t in threads:
570                 # TODO: optimize so that we only actually add that tracing if it's in
571                 # the new breakpoint context.
572                 additionalInfo = None
573                 try:
574                     additionalInfo = t.additionalInfo
575                 except AttributeError:
576                     pass  # that's ok, no info currently set
577
578                 if additionalInfo is not None:
579                     for frame in additionalInfo.IterFrames():
580                         if frame is not ignore_frame:
581                             self.SetTraceForFrameAndParents(frame, overwrite_prev_trace=overwrite_prev_trace)
582         finally:
583             frame = None
584             t = None
585             threads = None
586             additionalInfo = None
587
588
589     def consolidate_breakpoints(self, file, id_to_breakpoint, breakpoints):
590         break_dict = {}
591         for breakpoint_id, pybreakpoint in DictIterItems(id_to_breakpoint):
592             break_dict[pybreakpoint.line] = pybreakpoint
593
594         breakpoints[file] = break_dict
595
596     def add_break_on_exception(
597         self,
598         exception,
599         notify_always,
600         notify_on_terminate,
601         notify_on_first_raise_only,
602         ):
603         try:
604             eb = ExceptionBreakpoint(
605                 exception,
606                 notify_always,
607                 notify_on_terminate,
608                 notify_on_first_raise_only,
609             )
610         except ImportError:
611             pydev_log.error("Error unable to add break on exception for: %s (exception could not be imported)\n" % (exception,))
612             return None
613
614         if eb.notify_on_terminate:
615             cp = self.break_on_uncaught_exceptions.copy()
616             cp[exception] = eb
617             if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
618                 pydev_log.error("Exceptions to hook on terminate: %s\n" % (cp,))
619             self.break_on_uncaught_exceptions = cp
620
621         if eb.notify_always:
622             cp = self.break_on_caught_exceptions.copy()
623             cp[exception] = eb
624             if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
625                 pydev_log.error("Exceptions to hook always: %s\n" % (cp,))
626             self.break_on_caught_exceptions = cp
627
628         return eb
629
630     def update_after_exceptions_added(self, added):
631         updated_on_caught = False
632         updated_on_uncaught = False
633
634         for eb in added:
635             if not updated_on_uncaught and eb.notify_on_terminate:
636                 updated_on_uncaught = True
637                 update_exception_hook(self)
638
639             if not updated_on_caught and eb.notify_always:
640                 updated_on_caught = True
641                 self.setTracingForUntracedContexts()
642
643
644     def processNetCommand(self, cmd_id, seq, text):
645         '''Processes a command received from the Java side
646
647         @param cmd_id: the id of the command
648         @param seq: the sequence of the command
649         @param text: the text received in the command
650
651         @note: this method is run as a big switch... after doing some tests, it's not clear whether changing it for
652         a dict id --> function call will have better performance result. A simple test with xrange(10000000) showed
653         that the gains from having a fast access to what should be executed are lost because of the function call in
654         a way that if we had 10 elements in the switch the if..elif are better -- but growing the number of choices
655         makes the solution with the dispatch look better -- so, if this gets more than 20-25 choices at some time,
656         it may be worth refactoring it (actually, reordering the ifs so that the ones used mostly come before
657         probably will give better performance).
658         '''
659         #print(ID_TO_MEANING[str(cmd_id)], repr(text))
660
661         self._main_lock.acquire()
662         try:
663             try:
664                 cmd = None
665                 if cmd_id == CMD_RUN:
666                     self.readyToRun = True
667
668                 elif cmd_id == CMD_VERSION:
669                     # response is version number
670                     # ide_os should be 'WINDOWS' or 'UNIX'.
671                     ide_os = 'WINDOWS'
672
673                     # Breakpoints can be grouped by 'LINE' or by 'ID'.
674                     breakpoints_by = 'LINE'
675
676                     splitted = text.split('\t')
677                     if len(splitted) == 1:
678                         _local_version = splitted
679
680                     elif len(splitted) == 2:
681                         _local_version, ide_os = splitted
682
683                     elif len(splitted) == 3:
684                         _local_version, ide_os, breakpoints_by = splitted
685
686                     if breakpoints_by == 'ID':
687                         self._set_breakpoints_with_id = True
688                     else:
689                         self._set_breakpoints_with_id = False
690
691                     pydevd_file_utils.set_ide_os(ide_os)
692
693                     cmd = self.cmdFactory.makeVersionMessage(seq)
694
695                 elif cmd_id == CMD_LIST_THREADS:
696                     # response is a list of threads
697                     cmd = self.cmdFactory.makeListThreadsMessage(seq)
698
699                 elif cmd_id == CMD_THREAD_KILL:
700                     int_cmd = InternalTerminateThread(text)
701                     self.postInternalCommand(int_cmd, text)
702
703                 elif cmd_id == CMD_THREAD_SUSPEND:
704                     # Yes, thread suspend is still done at this point, not through an internal command!
705                     t = PydevdFindThreadById(text)
706                     if t:
707                         additionalInfo = None
708                         try:
709                             additionalInfo = t.additionalInfo
710                         except AttributeError:
711                             pass  # that's ok, no info currently set
712
713                         if additionalInfo is not None:
714                             for frame in additionalInfo.IterFrames():
715                                 self.SetTraceForFrameAndParents(frame)
716                                 del frame
717
718                         self.setSuspend(t, CMD_THREAD_SUSPEND)
719                     elif text.startswith('__frame__:'):
720                         sys.stderr.write("Can't suspend tasklet: %s\n" % (text,))
721
722                 elif cmd_id == CMD_THREAD_RUN:
723                     t = PydevdFindThreadById(text)
724                     if t:
725                         thread_id = GetThreadId(t)
726                         int_cmd = InternalRunThread(thread_id)
727                         self.postInternalCommand(int_cmd, thread_id)
728
729                     elif text.startswith('__frame__:'):
730                         sys.stderr.write("Can't make tasklet run: %s\n" % (text,))
731
732
733                 elif cmd_id == CMD_STEP_INTO or cmd_id == CMD_STEP_OVER or cmd_id == CMD_STEP_RETURN:
734                     # we received some command to make a single step
735                     t = PydevdFindThreadById(text)
736                     if t:
737                         thread_id = GetThreadId(t)
738                         int_cmd = InternalStepThread(thread_id, cmd_id)
739                         self.postInternalCommand(int_cmd, thread_id)
740
741                     elif text.startswith('__frame__:'):
742                         sys.stderr.write("Can't make tasklet step command: %s\n" % (text,))
743
744
745                 elif cmd_id == CMD_RUN_TO_LINE or cmd_id == CMD_SET_NEXT_STATEMENT or cmd_id == CMD_SMART_STEP_INTO:
746                     # we received some command to make a single step
747                     thread_id, line, func_name = text.split('\t', 2)
748                     t = PydevdFindThreadById(thread_id)
749                     if t:
750                         int_cmd = InternalSetNextStatementThread(thread_id, cmd_id, line, func_name)
751                         self.postInternalCommand(int_cmd, thread_id)
752                     elif thread_id.startswith('__frame__:'):
753                         sys.stderr.write("Can't set next statement in tasklet: %s\n" % (thread_id,))
754
755
756                 elif cmd_id == CMD_RELOAD_CODE:
757                     # we received some command to make a reload of a module
758                     module_name = text.strip()
759
760                     thread_id = '*'  # Any thread
761
762                     # Note: not going for the main thread because in this case it'd only do the load
763                     # when we stopped on a breakpoint.
764                     # for tid, t in self._running_thread_ids.items(): #Iterate in copy
765                     #    thread_name = t.getName()
766                     #
767                     #    print thread_name, GetThreadId(t)
768                     #    #Note: if possible, try to reload on the main thread
769                     #    if thread_name == 'MainThread':
770                     #        thread_id = tid
771
772                     int_cmd = ReloadCodeCommand(module_name, thread_id)
773                     self.postInternalCommand(int_cmd, thread_id)
774
775
776                 elif cmd_id == CMD_CHANGE_VARIABLE:
777                     # the text is: thread\tstackframe\tFRAME|GLOBAL\tattribute_to_change\tvalue_to_change
778                     try:
779                         thread_id, frame_id, scope, attr_and_value = text.split('\t', 3)
780
781                         tab_index = attr_and_value.rindex('\t')
782                         attr = attr_and_value[0:tab_index].replace('\t', '.')
783                         value = attr_and_value[tab_index + 1:]
784                         int_cmd = InternalChangeVariable(seq, thread_id, frame_id, scope, attr, value)
785                         self.postInternalCommand(int_cmd, thread_id)
786
787                     except:
788                         traceback.print_exc()
789
790                 elif cmd_id == CMD_GET_VARIABLE:
791                     # we received some command to get a variable
792                     # the text is: thread_id\tframe_id\tFRAME|GLOBAL\tattributes*
793                     try:
794                         thread_id, frame_id, scopeattrs = text.split('\t', 2)
795
796                         if scopeattrs.find('\t') != -1:  # there are attributes beyond scope
797                             scope, attrs = scopeattrs.split('\t', 1)
798                         else:
799                             scope, attrs = (scopeattrs, None)
800
801                         int_cmd = InternalGetVariable(seq, thread_id, frame_id, scope, attrs)
802                         self.postInternalCommand(int_cmd, thread_id)
803
804                     except:
805                         traceback.print_exc()
806
807                 elif cmd_id == CMD_GET_ARRAY:
808                     # we received some command to get an array variable
809                     # the text is: thread_id\tframe_id\tFRAME|GLOBAL\tname\ttemp\troffs\tcoffs\trows\tcols\tformat
810                     try:
811                         roffset, coffset, rows, cols, format, thread_id, frame_id, scopeattrs  = text.split('\t', 7)
812
813                         if scopeattrs.find('\t') != -1:  # there are attributes beyond scope
814                             scope, attrs = scopeattrs.split('\t', 1)
815                         else:
816                             scope, attrs = (scopeattrs, None)
817
818                         int_cmd = InternalGetArray(seq, roffset, coffset, rows, cols, format, thread_id, frame_id, scope, attrs)
819                         self.postInternalCommand(int_cmd, thread_id)
820
821                     except:
822                         traceback.print_exc()
823
824                 elif cmd_id == CMD_GET_COMPLETIONS:
825                     # we received some command to get a variable
826                     # the text is: thread_id\tframe_id\tactivation token
827                     try:
828                         thread_id, frame_id, scope, act_tok = text.split('\t', 3)
829
830                         int_cmd = InternalGetCompletions(seq, thread_id, frame_id, act_tok)
831                         self.postInternalCommand(int_cmd, thread_id)
832
833                     except:
834                         traceback.print_exc()
835
836                 elif cmd_id == CMD_GET_FRAME:
837                     thread_id, frame_id, scope = text.split('\t', 2)
838
839                     int_cmd = InternalGetFrame(seq, thread_id, frame_id)
840                     self.postInternalCommand(int_cmd, thread_id)
841
842                 elif cmd_id == CMD_SET_BREAK:
843                     # func name: 'None': match anything. Empty: match global, specified: only method context.
844                     # command to add some breakpoint.
845                     # text is file\tline. Add to breakpoints dictionary
846                     if self._set_breakpoints_with_id:
847                         breakpoint_id, type, file, line, func_name, condition, expression = text.split('\t', 6)
848
849                         breakpoint_id = int(breakpoint_id)
850                         line = int(line)
851
852                         # We must restore new lines and tabs as done in
853                         # AbstractDebugTarget.breakpointAdded
854                         condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n').\
855                             replace("@_@TAB_CHAR@_@", '\t').strip()
856
857                         expression = expression.replace("@_@NEW_LINE_CHAR@_@", '\n').\
858                             replace("@_@TAB_CHAR@_@", '\t').strip()
859                     else:
860                         #Note: this else should be removed after PyCharm migrates to setting
861                         #breakpoints by id (and ideally also provides func_name).
862                         type, file, line, func_name, condition, expression = text.split('\t', 5)
863                         # If we don't have an id given for each breakpoint, consider
864                         # the id to be the line.
865                         breakpoint_id = line = int(line)
866
867                         condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n'). \
868                             replace("@_@TAB_CHAR@_@", '\t').strip()
869
870                         expression = expression.replace("@_@NEW_LINE_CHAR@_@", '\n'). \
871                             replace("@_@TAB_CHAR@_@", '\t').strip()
872
873                     if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
874                         file = file.encode(file_system_encoding)
875
876                     file = NormFileToServer(file)
877
878                     if not pydevd_file_utils.exists(file):
879                         sys.stderr.write('pydev debugger: warning: trying to add breakpoint'\
880                             ' to file that does not exist: %s (will have no effect)\n' % (file,))
881                         sys.stderr.flush()
882
883
884                     if len(condition) <= 0 or condition is None or condition == "None":
885                         condition = None
886
887                     if len(expression) <= 0 or expression is None or expression == "None":
888                         expression = None
889
890                     supported_type = False
891                     if type == 'python-line':
892                         breakpoint = LineBreakpoint(line, condition, func_name, expression)
893                         breakpoints = self.breakpoints
894                         file_to_id_to_breakpoint = self.file_to_id_to_line_breakpoint
895                         supported_type = True
896                     else:
897                         result = None
898                         plugin = self.get_plugin_lazy_init()
899                         if plugin is not None:
900                             result = plugin.add_breakpoint('add_line_breakpoint', self, type, file, line, condition, expression, func_name)
901                         if result is not None:
902                             supported_type = True
903                             breakpoint, breakpoints = result
904                             file_to_id_to_breakpoint = self.file_to_id_to_plugin_breakpoint
905                         else:
906                             supported_type = False
907
908                     if not supported_type:
909                         raise NameError(type)
910
911                     if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
912                         pydev_log.debug('Added breakpoint:%s - line:%s - func_name:%s\n' % (file, line, func_name.encode('utf-8')))
913                         sys.stderr.flush()
914
915                     if DictContains(file_to_id_to_breakpoint, file):
916                         id_to_pybreakpoint = file_to_id_to_breakpoint[file]
917                     else:
918                         id_to_pybreakpoint = file_to_id_to_breakpoint[file] = {}
919
920                     id_to_pybreakpoint[breakpoint_id] = breakpoint
921                     self.consolidate_breakpoints(file, id_to_pybreakpoint, breakpoints)
922                     if self.plugin is not None:
923                         self.has_plugin_line_breaks = self.plugin.has_line_breaks()
924
925                     self.setTracingForUntracedContexts(overwrite_prev_trace=True)
926
927                 elif cmd_id == CMD_REMOVE_BREAK:
928                     #command to remove some breakpoint
929                     #text is type\file\tid. Remove from breakpoints dictionary
930                     breakpoint_type, file, breakpoint_id = text.split('\t', 2)
931
932                     if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
933                         file = file.encode(file_system_encoding)
934
935                     file = NormFileToServer(file)
936
937                     try:
938                         breakpoint_id = int(breakpoint_id)
939                     except ValueError:
940                         pydev_log.error('Error removing breakpoint. Expected breakpoint_id to be an int. Found: %s' % (breakpoint_id,))
941
942                     else:
943                         file_to_id_to_breakpoint = None
944                         if breakpoint_type == 'python-line':
945                             breakpoints = self.breakpoints
946                             file_to_id_to_breakpoint = self.file_to_id_to_line_breakpoint
947                         elif self.get_plugin_lazy_init() is not None:
948                             result = self.plugin.get_breakpoints(self, breakpoint_type)
949                             if result is not None:
950                                 file_to_id_to_breakpoint = self.file_to_id_to_plugin_breakpoint
951                                 breakpoints = result
952
953                         if file_to_id_to_breakpoint is None:
954                             pydev_log.error('Error removing breakpoint. Cant handle breakpoint of type %s' % breakpoint_type)
955                         else:
956                             try:
957                                 id_to_pybreakpoint = file_to_id_to_breakpoint.get(file, {})
958                                 if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
959                                     existing = id_to_pybreakpoint[breakpoint_id]
960                                     sys.stderr.write('Removed breakpoint:%s - line:%s - func_name:%s (id: %s)\n' % (
961                                         file, existing.line, existing.func_name.encode('utf-8'), breakpoint_id))
962
963                                 del id_to_pybreakpoint[breakpoint_id]
964                                 self.consolidate_breakpoints(file, id_to_pybreakpoint, breakpoints)
965                                 if self.plugin is not None:
966                                     self.has_plugin_line_breaks = self.plugin.has_line_breaks()
967
968                             except KeyError:
969                                 pydev_log.error("Error removing breakpoint: Breakpoint id not found: %s id: %s. Available ids: %s\n" % (
970                                     file, breakpoint_id, DictKeys(id_to_pybreakpoint)))
971
972
973                 elif cmd_id == CMD_EVALUATE_EXPRESSION or cmd_id == CMD_EXEC_EXPRESSION:
974                     #command to evaluate the given expression
975                     #text is: thread\tstackframe\tLOCAL\texpression
976                     thread_id, frame_id, scope, expression, trim = text.split('\t', 4)
977                     int_cmd = InternalEvaluateExpression(seq, thread_id, frame_id, expression,
978                         cmd_id == CMD_EXEC_EXPRESSION, int(trim) == 1)
979                     self.postInternalCommand(int_cmd, thread_id)
980
981                 elif cmd_id == CMD_CONSOLE_EXEC:
982                     #command to exec expression in console, in case expression is only partially valid 'False' is returned
983                     #text is: thread\tstackframe\tLOCAL\texpression
984
985                     thread_id, frame_id, scope, expression = text.split('\t', 3)
986
987                     int_cmd = InternalConsoleExec(seq, thread_id, frame_id, expression)
988                     self.postInternalCommand(int_cmd, thread_id)
989
990                 elif cmd_id == CMD_SET_PY_EXCEPTION:
991                     # Command which receives set of exceptions on which user wants to break the debugger
992                     # text is: break_on_uncaught;break_on_caught;TypeError;ImportError;zipimport.ZipImportError;
993                     # This API is optional and works 'in bulk' -- it's possible
994                     # to get finer-grained control with CMD_ADD_EXCEPTION_BREAK/CMD_REMOVE_EXCEPTION_BREAK
995                     # which allows setting caught/uncaught per exception.
996                     #
997                     splitted = text.split(';')
998                     self.break_on_uncaught_exceptions = {}
999                     self.break_on_caught_exceptions = {}
1000                     added = []
1001                     if len(splitted) >= 4:
1002                         if splitted[0] == 'true':
1003                             break_on_uncaught = True
1004                         else:
1005                             break_on_uncaught = False
1006
1007                         if splitted[1] == 'true':
1008                             break_on_caught = True
1009                         else:
1010                             break_on_caught = False
1011
1012                         if splitted[2] == 'true':
1013                             self.break_on_exceptions_thrown_in_same_context = True
1014                         else:
1015                             self.break_on_exceptions_thrown_in_same_context = False
1016
1017                         if splitted[3] == 'true':
1018                             self.ignore_exceptions_thrown_in_lines_with_ignore_exception = True
1019                         else:
1020                             self.ignore_exceptions_thrown_in_lines_with_ignore_exception = False
1021
1022                         for exception_type in splitted[4:]:
1023                             exception_type = exception_type.strip()
1024                             if not exception_type:
1025                                 continue
1026
1027                             exception_breakpoint = self.add_break_on_exception(
1028                                 exception_type,
1029                                 notify_always=break_on_caught,
1030                                 notify_on_terminate=break_on_uncaught,
1031                                 notify_on_first_raise_only=False,
1032                             )
1033                             if exception_breakpoint is None:
1034                                 continue
1035                             added.append(exception_breakpoint)
1036
1037                         self.update_after_exceptions_added(added)
1038
1039                     else:
1040                         sys.stderr.write("Error when setting exception list. Received: %s\n" % (text,))
1041
1042                 elif cmd_id == CMD_GET_FILE_CONTENTS:
1043
1044                     if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
1045                         text = text.encode(file_system_encoding)
1046
1047                     if os.path.exists(text):
1048                         f = open(text, 'r')
1049                         try:
1050                             source = f.read()
1051                         finally:
1052                             f.close()
1053                         cmd = self.cmdFactory.makeGetFileContents(seq, source)
1054
1055                 elif cmd_id == CMD_SET_PROPERTY_TRACE:
1056                     # Command which receives whether to trace property getter/setter/deleter
1057                     # text is feature_state(true/false);disable_getter/disable_setter/disable_deleter
1058                     if text != "":
1059                         splitted = text.split(';')
1060                         if len(splitted) >= 3:
1061                             if self.disable_property_trace is False and splitted[0] == 'true':
1062                                 # Replacing property by custom property only when the debugger starts
1063                                 pydevd_traceproperty.replace_builtin_property()
1064                                 self.disable_property_trace = True
1065                             # Enable/Disable tracing of the property getter
1066                             if splitted[1] == 'true':
1067                                 self.disable_property_getter_trace = True
1068                             else:
1069                                 self.disable_property_getter_trace = False
1070                             # Enable/Disable tracing of the property setter
1071                             if splitted[2] == 'true':
1072                                 self.disable_property_setter_trace = True
1073                             else:
1074                                 self.disable_property_setter_trace = False
1075                             # Enable/Disable tracing of the property deleter
1076                             if splitted[3] == 'true':
1077                                 self.disable_property_deleter_trace = True
1078                             else:
1079                                 self.disable_property_deleter_trace = False
1080                     else:
1081                         # User hasn't configured any settings for property tracing
1082                         pass
1083
1084                 elif cmd_id == CMD_ADD_EXCEPTION_BREAK:
1085                     if text.find('\t') != -1:
1086                         exception, notify_always, notify_on_terminate = text.split('\t', 2)
1087                     else:
1088                         exception, notify_always, notify_on_terminate = text, 0, 0
1089
1090                     if exception.find('-') != -1:
1091                         type, exception = exception.split('-')
1092                     else:
1093                         type = 'python'
1094
1095                     if type == 'python':
1096                         exception_breakpoint = self.add_break_on_exception(
1097                             exception,
1098                             notify_always=int(notify_always) > 0,
1099                             notify_on_terminate = int(notify_on_terminate) == 1,
1100                             notify_on_first_raise_only=int(notify_always) == 2
1101                         )
1102
1103                         if exception_breakpoint is not None:
1104                             self.update_after_exceptions_added([exception_breakpoint])
1105                     else:
1106                         supported_type = False
1107                         plugin = self.get_plugin_lazy_init()
1108                         if plugin is not None:
1109                             supported_type = plugin.add_breakpoint('add_exception_breakpoint', self, type, exception)
1110
1111                         if supported_type:
1112                             self.has_plugin_exception_breaks = self.plugin.has_exception_breaks()
1113                         else:
1114                             raise NameError(type)
1115
1116
1117
1118                 elif cmd_id == CMD_REMOVE_EXCEPTION_BREAK:
1119                     exception = text
1120                     if exception.find('-') != -1:
1121                         type, exception = exception.split('-')
1122                     else:
1123                         type = 'python'
1124
1125                     if type == 'python':
1126                         try:
1127                             cp = self.break_on_uncaught_exceptions.copy()
1128                             DictPop(cp, exception, None)
1129                             self.break_on_uncaught_exceptions = cp
1130
1131                             cp = self.break_on_caught_exceptions.copy()
1132                             DictPop(cp, exception, None)
1133                             self.break_on_caught_exceptions = cp
1134                         except:
1135                             pydev_log.debug("Error while removing exception %s"%sys.exc_info()[0])
1136                         update_exception_hook(self)
1137                     else:
1138                         supported_type = False
1139                         
1140                         # I.e.: no need to initialize lazy (if we didn't have it in the first place, we can't remove
1141                         # anything from it anyways).
1142                         plugin = self.plugin 
1143                         if plugin is not None:
1144                             supported_type = plugin.remove_exception_breakpoint(self, type, exception)
1145
1146                         if supported_type:
1147                             self.has_plugin_exception_breaks = self.plugin.has_exception_breaks()
1148                         else:
1149                             raise NameError(type)
1150
1151                 elif cmd_id == CMD_LOAD_SOURCE:
1152                     path = text
1153                     try:
1154                         f = open(path, 'r')
1155                         source = f.read()
1156                         self.cmdFactory.makeLoadSourceMessage(seq, source, self)
1157                     except:
1158                         return self.cmdFactory.makeErrorMessage(seq, pydevd_tracing.GetExceptionTracebackStr())
1159
1160                 elif cmd_id == CMD_ADD_DJANGO_EXCEPTION_BREAK:
1161                     exception = text
1162                     plugin = self.get_plugin_lazy_init()
1163                     if plugin is not None:
1164                         plugin.add_breakpoint('add_exception_breakpoint', self, 'django', exception)
1165                         self.has_plugin_exception_breaks = self.plugin.has_exception_breaks()
1166
1167
1168                 elif cmd_id == CMD_REMOVE_DJANGO_EXCEPTION_BREAK:
1169                     exception = text
1170
1171                     # I.e.: no need to initialize lazy (if we didn't have it in the first place, we can't remove
1172                     # anything from it anyways).
1173                     plugin = self.plugin
1174                     if plugin is not None:
1175                         plugin.remove_exception_breakpoint(self, 'django', exception)
1176                         self.has_plugin_exception_breaks = self.plugin.has_exception_breaks()
1177
1178                 elif cmd_id == CMD_EVALUATE_CONSOLE_EXPRESSION:
1179                     # Command which takes care for the debug console communication
1180                     if text != "":
1181                         thread_id, frame_id, console_command = text.split('\t', 2)
1182                         console_command, line = console_command.split('\t')
1183                         if console_command == 'EVALUATE':
1184                             int_cmd = InternalEvaluateConsoleExpression(seq, thread_id, frame_id, line)
1185                         elif console_command == 'GET_COMPLETIONS':
1186                             int_cmd = InternalConsoleGetCompletions(seq, thread_id, frame_id, line)
1187                         self.postInternalCommand(int_cmd, thread_id)
1188
1189                 elif cmd_id == CMD_RUN_CUSTOM_OPERATION:
1190                     # Command which runs a custom operation
1191                     if text != "":
1192                         try:
1193                             location, custom = text.split('||', 1)
1194                         except:
1195                             sys.stderr.write('Custom operation now needs a || separator. Found: %s\n' % (text,))
1196                             raise
1197
1198                         thread_id, frame_id, scopeattrs = location.split('\t', 2)
1199
1200                         if scopeattrs.find('\t') != -1:  # there are attributes beyond scope
1201                             scope, attrs = scopeattrs.split('\t', 1)
1202                         else:
1203                             scope, attrs = (scopeattrs, None)
1204
1205                         # : style: EXECFILE or EXEC
1206                         # : encoded_code_or_file: file to execute or code
1207                         # : fname: name of function to be executed in the resulting namespace
1208                         style, encoded_code_or_file, fnname = custom.split('\t', 3)
1209                         int_cmd = InternalRunCustomOperation(seq, thread_id, frame_id, scope, attrs,
1210                                                              style, encoded_code_or_file, fnname)
1211                         self.postInternalCommand(int_cmd, thread_id)
1212
1213                 elif cmd_id == CMD_IGNORE_THROWN_EXCEPTION_AT:
1214                     if text:
1215                         replace = 'REPLACE:'  # Not all 3.x versions support u'REPLACE:', so, doing workaround.
1216                         if not IS_PY3K:
1217                             replace = unicode(replace)
1218
1219                         if text.startswith(replace):
1220                             text = text[8:]
1221                             self.filename_to_lines_where_exceptions_are_ignored.clear()
1222
1223                         if text:
1224                             for line in text.split('||'):  # Can be bulk-created (one in each line)
1225                                 filename, line_number = line.split('|')
1226                                 if not IS_PY3K:
1227                                     filename = filename.encode(file_system_encoding)
1228
1229                                 filename = NormFileToServer(filename)
1230
1231                                 if os.path.exists(filename):
1232                                     lines_ignored = self.filename_to_lines_where_exceptions_are_ignored.get(filename)
1233                                     if lines_ignored is None:
1234                                         lines_ignored = self.filename_to_lines_where_exceptions_are_ignored[filename] = {}
1235                                     lines_ignored[int(line_number)] = 1
1236                                 else:
1237                                     sys.stderr.write('pydev debugger: warning: trying to ignore exception thrown'\
1238                                         ' on file that does not exist: %s (will have no effect)\n' % (filename,))
1239
1240                 elif cmd_id == CMD_ENABLE_DONT_TRACE:
1241                     if text:
1242                         true_str = 'true'  # Not all 3.x versions support u'str', so, doing workaround.
1243                         if not IS_PY3K:
1244                             true_str = unicode(true_str)
1245
1246                         mode = text.strip() == true_str
1247                         pydevd_dont_trace.trace_filter(mode)
1248
1249                 else:
1250                     #I have no idea what this is all about
1251                     cmd = self.cmdFactory.makeErrorMessage(seq, "unexpected command " + str(cmd_id))
1252
1253                 if cmd is not None:
1254                     self.writer.addCommand(cmd)
1255                     del cmd
1256
1257             except Exception:
1258                 traceback.print_exc()
1259                 cmd = self.cmdFactory.makeErrorMessage(seq,
1260                     "Unexpected exception in processNetCommand.\nInitial params: %s" % ((cmd_id, seq, text),))
1261
1262                 self.writer.addCommand(cmd)
1263         finally:
1264             self._main_lock.release()
1265
1266     def processThreadNotAlive(self, threadId):
1267         """ if thread is not alive, cancel trace_dispatch processing """
1268         self._lock_running_thread_ids.acquire()
1269         try:
1270             thread = self._running_thread_ids.pop(threadId, None)
1271             if thread is None:
1272                 return
1273
1274             wasNotified = thread.additionalInfo.pydev_notify_kill
1275             if not wasNotified:
1276                 thread.additionalInfo.pydev_notify_kill = True
1277
1278         finally:
1279             self._lock_running_thread_ids.release()
1280
1281         cmd = self.cmdFactory.makeThreadKilledMessage(threadId)
1282         self.writer.addCommand(cmd)
1283
1284
1285     def setSuspend(self, thread, stop_reason):
1286         thread.additionalInfo.suspend_type = PYTHON_SUSPEND
1287         thread.additionalInfo.pydev_state = STATE_SUSPEND
1288         thread.stop_reason = stop_reason
1289
1290         # If conditional breakpoint raises any exception during evaluation send details to Java
1291         if stop_reason == CMD_SET_BREAK and self.suspend_on_breakpoint_exception:
1292             self.sendBreakpointConditionException(thread)
1293
1294
1295     def sendBreakpointConditionException(self, thread):
1296         """If conditional breakpoint raises an exception during evaluation
1297         send exception details to java
1298         """
1299         thread_id = GetThreadId(thread)
1300         conditional_breakpoint_exception_tuple = thread.additionalInfo.conditional_breakpoint_exception
1301         # conditional_breakpoint_exception_tuple - should contain 2 values (exception_type, stacktrace)
1302         if conditional_breakpoint_exception_tuple and len(conditional_breakpoint_exception_tuple) == 2:
1303             exc_type, stacktrace = conditional_breakpoint_exception_tuple
1304             int_cmd = InternalGetBreakpointException(thread_id, exc_type, stacktrace)
1305             # Reset the conditional_breakpoint_exception details to None
1306             thread.additionalInfo.conditional_breakpoint_exception = None
1307             self.postInternalCommand(int_cmd, thread_id)
1308
1309
1310     def sendCaughtExceptionStack(self, thread, arg, curr_frame_id):
1311         """Sends details on the exception which was caught (and where we stopped) to the java side.
1312
1313         arg is: exception type, description, traceback object
1314         """
1315         thread_id = GetThreadId(thread)
1316         int_cmd = InternalSendCurrExceptionTrace(thread_id, arg, curr_frame_id)
1317         self.postInternalCommand(int_cmd, thread_id)
1318
1319
1320     def sendCaughtExceptionStackProceeded(self, thread):
1321         """Sends that some thread was resumed and is no longer showing an exception trace.
1322         """
1323         thread_id = GetThreadId(thread)
1324         int_cmd = InternalSendCurrExceptionTraceProceeded(thread_id)
1325         self.postInternalCommand(int_cmd, thread_id)
1326         self.processInternalCommands()
1327
1328
1329     def doWaitSuspend(self, thread, frame, event, arg): #@UnusedVariable
1330         """ busy waits until the thread state changes to RUN
1331         it expects thread's state as attributes of the thread.
1332         Upon running, processes any outstanding Stepping commands.
1333         """
1334         self.processInternalCommands()
1335
1336         message = getattr(thread.additionalInfo, "message", None)
1337
1338         cmd = self.cmdFactory.makeThreadSuspendMessage(GetThreadId(thread), frame, thread.stop_reason, message)
1339         self.writer.addCommand(cmd)
1340
1341         CustomFramesContainer.custom_frames_lock.acquire()
1342         try:
1343             from_this_thread = []
1344
1345             for frame_id, custom_frame in DictIterItems(CustomFramesContainer.custom_frames):
1346                 if custom_frame.thread_id == thread.ident:
1347                     # print >> sys.stderr, 'Frame created: ', frame_id
1348                     self.writer.addCommand(self.cmdFactory.makeCustomFrameCreatedMessage(frame_id, custom_frame.name))
1349                     self.writer.addCommand(self.cmdFactory.makeThreadSuspendMessage(frame_id, custom_frame.frame, CMD_THREAD_SUSPEND, ""))
1350
1351                 from_this_thread.append(frame_id)
1352
1353         finally:
1354             CustomFramesContainer.custom_frames_lock.release()
1355
1356
1357
1358         info = thread.additionalInfo
1359         while info.pydev_state == STATE_SUSPEND and not self._finishDebuggingSession:
1360             self.processInternalCommands()
1361             time.sleep(0.01)
1362
1363         # process any stepping instructions
1364         if info.pydev_step_cmd == CMD_STEP_INTO:
1365             info.pydev_step_stop = None
1366             info.pydev_smart_step_stop = None
1367
1368         elif info.pydev_step_cmd == CMD_STEP_OVER:
1369             info.pydev_step_stop = frame
1370             info.pydev_smart_step_stop = None
1371             self.SetTraceForFrameAndParents(frame)
1372
1373         elif info.pydev_step_cmd == CMD_SMART_STEP_INTO:
1374             self.SetTraceForFrameAndParents(frame)
1375             info.pydev_step_stop = None
1376             info.pydev_smart_step_stop = frame
1377
1378         elif info.pydev_step_cmd == CMD_RUN_TO_LINE or info.pydev_step_cmd == CMD_SET_NEXT_STATEMENT :
1379             self.SetTraceForFrameAndParents(frame)
1380
1381             if event == 'line' or event == 'exception':
1382                 #If we're already in the correct context, we have to stop it now, because we can act only on
1383                 #line events -- if a return was the next statement it wouldn't work (so, we have this code
1384                 #repeated at pydevd_frame).
1385                 stop = False
1386                 curr_func_name = frame.f_code.co_name
1387
1388                 #global context is set with an empty name
1389                 if curr_func_name in ('?', '<module>'):
1390                     curr_func_name = ''
1391
1392                 if curr_func_name == info.pydev_func_name:
1393                     line = info.pydev_next_line
1394                     if frame.f_lineno == line:
1395                         stop = True
1396                     else :
1397                         if frame.f_trace is None:
1398                             frame.f_trace = self.trace_dispatch
1399                         frame.f_lineno = line
1400                         frame.f_trace = None
1401                         stop = True
1402                 if stop:
1403                     info.pydev_state = STATE_SUSPEND
1404                     self.doWaitSuspend(thread, frame, event, arg)
1405                     return
1406
1407
1408         elif info.pydev_step_cmd == CMD_STEP_RETURN:
1409             back_frame = frame.f_back
1410             if back_frame is not None:
1411                 # steps back to the same frame (in a return call it will stop in the 'back frame' for the user)
1412                 info.pydev_step_stop = frame
1413                 self.SetTraceForFrameAndParents(frame)
1414             else:
1415                 # No back frame?!? -- this happens in jython when we have some frame created from an awt event
1416                 # (the previous frame would be the awt event, but this doesn't make part of 'jython', only 'java')
1417                 # so, if we're doing a step return in this situation, it's the same as just making it run
1418                 info.pydev_step_stop = None
1419                 info.pydev_step_cmd = None
1420                 info.pydev_state = STATE_RUN
1421
1422         del frame
1423         cmd = self.cmdFactory.makeThreadRunMessage(GetThreadId(thread), info.pydev_step_cmd)
1424         self.writer.addCommand(cmd)
1425
1426         CustomFramesContainer.custom_frames_lock.acquire()
1427         try:
1428             # The ones that remained on last_running must now be removed.
1429             for frame_id in from_this_thread:
1430                 # print >> sys.stderr, 'Removing created frame: ', frame_id
1431                 self.writer.addCommand(self.cmdFactory.makeThreadKilledMessage(frame_id))
1432
1433         finally:
1434             CustomFramesContainer.custom_frames_lock.release()
1435
1436     def handle_post_mortem_stop(self, additionalInfo, t):
1437         pydev_log.debug("We are stopping in post-mortem\n")
1438         frame, frames_byid = additionalInfo.pydev_force_stop_at_exception
1439         thread_id = GetThreadId(t)
1440         pydevd_vars.addAdditionalFrameById(thread_id, frames_byid)
1441         try:
1442             try:
1443                 add_exception_to_frame(frame, additionalInfo.exception)
1444                 self.setSuspend(t, CMD_ADD_EXCEPTION_BREAK)
1445                 self.doWaitSuspend(t, frame, 'exception', None)
1446             except:
1447                 pydev_log.error("We've got an error while stopping in post-mortem: %s\n"%sys.exc_info()[0])
1448         finally:
1449             additionalInfo.pydev_force_stop_at_exception = None
1450             pydevd_vars.removeAdditionalFrameById(thread_id)
1451
1452     def trace_dispatch(self, frame, event, arg):
1453         ''' This is the callback used when we enter some context in the debugger.
1454
1455         We also decorate the thread we are in with info about the debugging.
1456         The attributes added are:
1457             pydev_state
1458             pydev_step_stop
1459             pydev_step_cmd
1460             pydev_notify_kill
1461         '''
1462         try:
1463             if self._finishDebuggingSession and not self._terminationEventSent:
1464                 #that was not working very well because jython gave some socket errors
1465                 try:
1466                     if self.output_checker is None:
1467                         killAllPydevThreads()
1468                 except:
1469                     traceback.print_exc()
1470                 self._terminationEventSent = True
1471                 return None
1472
1473             filename, base = GetFilenameAndBase(frame)
1474
1475             is_file_to_ignore = DictContains(DONT_TRACE, base) #we don't want to debug threading or anything related to pydevd
1476
1477             #print('trace_dispatch', base, frame.f_lineno, event, frame.f_code.co_name, is_file_to_ignore)
1478             if is_file_to_ignore:
1479                 return None
1480
1481             try:
1482                 #this shouldn't give an exception, but it could happen... (python bug)
1483                 #see http://mail.python.org/pipermail/python-bugs-list/2007-June/038796.html
1484                 #and related bug: http://bugs.python.org/issue1733757
1485                 t = threadingCurrentThread()
1486             except:
1487                 frame.f_trace = self.trace_dispatch
1488                 return self.trace_dispatch
1489
1490             try:
1491                 additionalInfo = t.additionalInfo
1492                 if additionalInfo is None:
1493                     raise AttributeError()
1494             except:
1495                 t.additionalInfo = PyDBAdditionalThreadInfo()
1496                 additionalInfo = t.additionalInfo
1497
1498             if additionalInfo is None:
1499                 return None
1500
1501             if additionalInfo.is_tracing:
1502                 f = frame
1503                 while f is not None:
1504                     if 'trace_dispatch' == f.f_code.co_name:
1505                         _fname, bs = GetFilenameAndBase(f)
1506                         if bs == 'pydevd_frame.py':
1507                             return None  #we don't wan't to trace code invoked from pydevd_frame.trace_dispatch
1508                     f = f.f_back
1509
1510             # if thread is not alive, cancel trace_dispatch processing
1511             if not isThreadAlive(t):
1512                 self.processThreadNotAlive(GetThreadId(t))
1513                 return None  # suspend tracing
1514
1515             # each new frame...
1516             return additionalInfo.CreateDbFrame((self, filename, additionalInfo, t, frame)).trace_dispatch(frame, event, arg)
1517
1518         except SystemExit:
1519             return None
1520
1521         except Exception:
1522             # Log it
1523             try:
1524                 if traceback is not None:
1525                     # This can actually happen during the interpreter shutdown in Python 2.7
1526                     traceback.print_exc()
1527             except:
1528                 # Error logging? We're really in the interpreter shutdown...
1529                 # (https://github.com/fabioz/PyDev.Debugger/issues/8) 
1530                 pass
1531             return None
1532
1533     if USE_PSYCO_OPTIMIZATION:
1534         try:
1535             import psyco
1536             trace_dispatch = psyco.proxy(trace_dispatch)
1537             processNetCommand = psyco.proxy(processNetCommand)
1538             processInternalCommands = psyco.proxy(processInternalCommands)
1539             doWaitSuspend = psyco.proxy(doWaitSuspend)
1540             getInternalQueue = psyco.proxy(getInternalQueue)
1541         except ImportError:
1542             if hasattr(sys, 'exc_clear'):  # jython does not have it
1543                 sys.exc_clear()  # don't keep the traceback (let's keep it clear for when we go to the point of executing client code)
1544
1545             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"):
1546                 sys.stderr.write("pydev debugger: warning: psyco not available for speedups (the debugger will still work correctly, but a bit slower)\n")
1547                 sys.stderr.flush()
1548
1549
1550
1551     def SetTraceForFrameAndParents(self, frame, also_add_to_passed_frame=True, overwrite_prev_trace=False, dispatch_func=None):
1552         if dispatch_func is None:
1553             dispatch_func = self.trace_dispatch
1554
1555         if also_add_to_passed_frame:
1556             self.update_trace(frame, dispatch_func, overwrite_prev_trace)
1557
1558         frame = frame.f_back
1559         while frame:
1560             self.update_trace(frame, dispatch_func, overwrite_prev_trace)
1561
1562             frame = frame.f_back
1563         del frame
1564
1565     def update_trace(self, frame, dispatch_func, overwrite_prev):
1566         if frame.f_trace is None:
1567             frame.f_trace = dispatch_func
1568         else:
1569             if overwrite_prev:
1570                 frame.f_trace = dispatch_func
1571             else:
1572                 try:
1573                     #If it's the trace_exception, go back to the frame trace dispatch!
1574                     if frame.f_trace.im_func.__name__ == 'trace_exception':
1575                         frame.f_trace = frame.f_trace.im_self.trace_dispatch
1576                 except AttributeError:
1577                     pass
1578                 frame = frame.f_back
1579         del frame
1580
1581     def prepareToRun(self):
1582         ''' Shared code to prepare debugging by installing traces and registering threads '''
1583         self.patch_threads()
1584         pydevd_tracing.SetTrace(self.trace_dispatch)
1585
1586
1587         PyDBCommandThread(self).start()
1588         if self.signature_factory is not None:
1589             # we need all data to be sent to IDE even after program finishes
1590             CheckOutputThread(self).start()
1591
1592
1593     def patch_threads(self):
1594         try:
1595             # not available in jython!
1596             threading.settrace(self.trace_dispatch)  # for all future threads
1597         except:
1598             pass
1599
1600         from pydev_monkey import patch_thread_modules
1601         patch_thread_modules()
1602
1603
1604     def run(self, file, globals=None, locals=None, set_trace=True):
1605         if os.path.isdir(file):
1606             new_target = os.path.join(file, '__main__.py')
1607             if os.path.isfile(new_target):
1608                 file = new_target
1609
1610         if globals is None:
1611             m = save_main_module(file, 'pydevd')
1612             globals = m.__dict__
1613             try:
1614                 globals['__builtins__'] = __builtins__
1615             except NameError:
1616                 pass  # Not there on Jython...
1617
1618         if locals is None:
1619             locals = globals
1620
1621         if set_trace:
1622             # Predefined (writable) attributes: __name__ is the module's name;
1623             # __doc__ is the module's documentation string, or None if unavailable;
1624             # __file__ is the pathname of the file from which the module was loaded,
1625             # if it was loaded from a file. The __file__ attribute is not present for
1626             # C modules that are statically linked into the interpreter; for extension modules
1627             # loaded dynamically from a shared library, it is the pathname of the shared library file.
1628
1629
1630             # 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
1631             # debug and run.
1632             if m.__file__.startswith(sys.path[0]):
1633                 # print >> sys.stderr, 'Deleting: ', sys.path[0]
1634                 del sys.path[0]
1635
1636             # now, the local directory has to be added to the pythonpath
1637             # sys.path.insert(0, os.getcwd())
1638             # Changed: it's not the local directory, but the directory of the file launched
1639             # The file being run ust be in the pythonpath (even if it was not before)
1640             sys.path.insert(0, os.path.split(file)[0])
1641
1642             self.prepareToRun()
1643
1644             while not self.readyToRun:
1645                 time.sleep(0.1)  # busy wait until we receive run command
1646
1647
1648         pydev_imports.execfile(file, globals, locals)  # execute the script
1649
1650     def exiting(self):
1651         sys.stdout.flush()
1652         sys.stderr.flush()
1653         self.checkOutputRedirect()
1654         cmd = self.cmdFactory.makeExitMessage()
1655         self.writer.addCommand(cmd)
1656
1657     def wait_for_commands(self, globals):
1658         thread = threading.currentThread()
1659         import pydevd_frame_utils
1660         frame = pydevd_frame_utils.Frame(None, -1, pydevd_frame_utils.FCode("Console",
1661                                                                             os.path.abspath(os.path.dirname(__file__))), globals, globals)
1662         thread_id = GetThreadId(thread)
1663         import pydevd_vars
1664         pydevd_vars.addAdditionalFrameById(thread_id, {id(frame): frame})
1665
1666         cmd = self.cmdFactory.makeShowConsoleMessage(thread_id, frame)
1667         self.writer.addCommand(cmd)
1668
1669         while True:
1670             self.processInternalCommands()
1671             time.sleep(0.01)
1672
1673 def set_debug(setup):
1674     setup['DEBUG_RECORD_SOCKET_READS'] = True
1675     setup['DEBUG_TRACE_BREAKPOINTS'] = 1
1676     setup['DEBUG_TRACE_LEVEL'] = 3
1677
1678
1679 def processCommandLine(argv):
1680     """ parses the arguments.
1681         removes our arguments from the command line """
1682     setup = {}
1683     setup['client'] = ''
1684     setup['server'] = False
1685     setup['port'] = 0
1686     setup['file'] = ''
1687     setup['multiproc'] = False #Used by PyCharm (reuses connection: ssh tunneling)
1688     setup['multiprocess'] = False # Used by PyDev (creates new connection to ide)
1689     setup['save-signatures'] = False
1690     setup['print-in-debugger-startup'] = False
1691     setup['cmd-line'] = False
1692     i = 0
1693     del argv[0]
1694     while (i < len(argv)):
1695         if argv[i] == '--port':
1696             del argv[i]
1697             setup['port'] = int(argv[i])
1698             del argv[i]
1699         elif argv[i] == '--vm_type':
1700             del argv[i]
1701             setup['vm_type'] = argv[i]
1702             del argv[i]
1703         elif argv[i] == '--client':
1704             del argv[i]
1705             setup['client'] = argv[i]
1706             del argv[i]
1707         elif argv[i] == '--server':
1708             del argv[i]
1709             setup['server'] = True
1710         elif argv[i] == '--file':
1711             del argv[i]
1712             setup['file'] = argv[i]
1713             i = len(argv) # pop out, file is our last argument
1714         elif argv[i] == '--DEBUG_RECORD_SOCKET_READS':
1715             del argv[i]
1716             setup['DEBUG_RECORD_SOCKET_READS'] = True
1717         elif argv[i] == '--DEBUG':
1718             del argv[i]
1719             set_debug(setup)
1720         elif argv[i] == '--multiproc':
1721             del argv[i]
1722             setup['multiproc'] = True
1723         elif argv[i] == '--multiprocess':
1724             del argv[i]
1725             setup['multiprocess'] = True
1726         elif argv[i] == '--save-signatures':
1727             del argv[i]
1728             setup['save-signatures'] = True
1729         elif argv[i] == '--print-in-debugger-startup':
1730             del argv[i]
1731             setup['print-in-debugger-startup'] = True
1732         elif (argv[i] == '--cmd-line'):
1733             del argv[i]
1734             setup['cmd-line'] = True
1735         else:
1736             raise ValueError("unexpected option " + argv[i])
1737     return setup
1738
1739 def usage(doExit=0):
1740     sys.stdout.write('Usage:\n')
1741     sys.stdout.write('pydevd.py --port=N [(--client hostname) | --server] --file executable [file_options]\n')
1742     if doExit:
1743         sys.exit(0)
1744
1745
1746 def initStdoutRedirect():
1747     if not getattr(sys, 'stdoutBuf', None):
1748         sys.stdoutBuf = pydevd_io.IOBuf()
1749         sys.stdout_original = sys.stdout
1750         sys.stdout = pydevd_io.IORedirector(sys.stdout, sys.stdoutBuf) #@UndefinedVariable
1751
1752 def initStderrRedirect():
1753     if not getattr(sys, 'stderrBuf', None):
1754         sys.stderrBuf = pydevd_io.IOBuf()
1755         sys.stderr_original = sys.stderr
1756         sys.stderr = pydevd_io.IORedirector(sys.stderr, sys.stderrBuf) #@UndefinedVariable
1757
1758
1759 def has_data_to_redirect():
1760     if getattr(sys, 'stdoutBuf', None):
1761         if not sys.stdoutBuf.empty():
1762             return True
1763     if getattr(sys, 'stderrBuf', None):
1764         if not sys.stderrBuf.empty():
1765             return True
1766
1767     return False
1768
1769 #=======================================================================================================================
1770 # settrace
1771 #=======================================================================================================================
1772 def settrace(
1773     host=None,
1774     stdoutToServer=False,
1775     stderrToServer=False,
1776     port=5678,
1777     suspend=True,
1778     trace_only_current_thread=False,
1779     overwrite_prev_trace=False,
1780     patch_multiprocessing=False,
1781     ):
1782     '''Sets the tracing function with the pydev debug function and initializes needed facilities.
1783
1784     @param host: the user may specify another host, if the debug server is not in the same machine (default is the local
1785         host)
1786
1787     @param stdoutToServer: when this is true, the stdout is passed to the debug server
1788
1789     @param stderrToServer: when this is true, the stderr is passed to the debug server
1790         so that they are printed in its console and not in this process console.
1791
1792     @param port: specifies which port to use for communicating with the server (note that the server must be started
1793         in the same port). @note: currently it's hard-coded at 5678 in the client
1794
1795     @param suspend: whether a breakpoint should be emulated as soon as this function is called.
1796
1797     @param trace_only_current_thread: determines if only the current thread will be traced or all current and future
1798         threads will also have the tracing enabled.
1799
1800     @param overwrite_prev_trace: if True we'll reset the frame.f_trace of frames which are already being traced
1801
1802     @param patch_multiprocessing: if True we'll patch the functions which create new processes so that launched
1803         processes are debugged.
1804     '''
1805     _set_trace_lock.acquire()
1806     try:
1807         _locked_settrace(
1808             host,
1809             stdoutToServer,
1810             stderrToServer,
1811             port,
1812             suspend,
1813             trace_only_current_thread,
1814             overwrite_prev_trace,
1815             patch_multiprocessing,
1816         )
1817     finally:
1818         _set_trace_lock.release()
1819
1820
1821
1822 _set_trace_lock = _pydev_thread.allocate_lock()
1823
1824 def _locked_settrace(
1825     host,
1826     stdoutToServer,
1827     stderrToServer,
1828     port,
1829     suspend,
1830     trace_only_current_thread,
1831     overwrite_prev_trace,
1832     patch_multiprocessing,
1833     ):
1834     if patch_multiprocessing:
1835         try:
1836             import pydev_monkey #Jython 2.1 can't use it...
1837         except:
1838             pass
1839         else:
1840             pydev_monkey.patch_new_process_functions()
1841
1842     if host is None:
1843         import pydev_localhost
1844         host = pydev_localhost.get_localhost()
1845
1846     global connected
1847     global bufferStdOutToServer
1848     global bufferStdErrToServer
1849
1850     if not connected :
1851         pydevd_vm_type.SetupType()
1852
1853         debugger = PyDB()
1854         debugger.connect(host, port)  # Note: connect can raise error.
1855
1856         # Mark connected only if it actually succeeded.
1857         connected = True
1858         bufferStdOutToServer = stdoutToServer
1859         bufferStdErrToServer = stderrToServer
1860
1861         if bufferStdOutToServer:
1862             initStdoutRedirect()
1863
1864         if bufferStdErrToServer:
1865             initStderrRedirect()
1866
1867         debugger.SetTraceForFrameAndParents(GetFrame(), False, overwrite_prev_trace=overwrite_prev_trace)
1868
1869
1870         CustomFramesContainer.custom_frames_lock.acquire()
1871         try:
1872             for _frameId, custom_frame in DictIterItems(CustomFramesContainer.custom_frames):
1873                 debugger.SetTraceForFrameAndParents(custom_frame.frame, False)
1874         finally:
1875             CustomFramesContainer.custom_frames_lock.release()
1876
1877
1878         t = threadingCurrentThread()
1879         try:
1880             additionalInfo = t.additionalInfo
1881         except AttributeError:
1882             additionalInfo = PyDBAdditionalThreadInfo()
1883             t.additionalInfo = additionalInfo
1884
1885         while not debugger.readyToRun:
1886             time.sleep(0.1)  # busy wait until we receive run command
1887
1888         # note that we do that through pydevd_tracing.SetTrace so that the tracing
1889         # is not warned to the user!
1890         pydevd_tracing.SetTrace(debugger.trace_dispatch)
1891
1892         if not trace_only_current_thread:
1893             # Trace future threads?
1894             debugger.patch_threads()
1895
1896             # As this is the first connection, also set tracing for any untraced threads
1897             debugger.setTracingForUntracedContexts(ignore_frame=GetFrame(), overwrite_prev_trace=overwrite_prev_trace)
1898
1899         # Stop the tracing as the last thing before the actual shutdown for a clean exit.
1900         atexit.register(stoptrace)
1901         
1902         #Suspend as the last thing after all tracing is in place.
1903         if suspend:
1904             debugger.setSuspend(t, CMD_THREAD_SUSPEND)
1905
1906         PyDBCommandThread(debugger).start()
1907         CheckOutputThread(debugger).start()
1908
1909     else:
1910         # ok, we're already in debug mode, with all set, so, let's just set the break
1911         debugger = GetGlobalDebugger()
1912
1913         debugger.SetTraceForFrameAndParents(GetFrame(), False)
1914
1915         t = threadingCurrentThread()
1916         try:
1917             additionalInfo = t.additionalInfo
1918         except AttributeError:
1919             additionalInfo = PyDBAdditionalThreadInfo()
1920             t.additionalInfo = additionalInfo
1921
1922         pydevd_tracing.SetTrace(debugger.trace_dispatch)
1923
1924         if not trace_only_current_thread:
1925             # Trace future threads?
1926             debugger.patch_threads()
1927
1928
1929         if suspend:
1930             debugger.setSuspend(t, CMD_THREAD_SUSPEND)
1931
1932
1933 def stoptrace():
1934     global connected
1935     if connected:
1936         pydevd_tracing.RestoreSysSetTraceFunc()
1937         sys.settrace(None)
1938         try:
1939             #not available in jython!
1940             threading.settrace(None) # for all future threads
1941         except:
1942             pass
1943
1944         from pydev_monkey import undo_patch_thread_modules
1945         undo_patch_thread_modules()
1946  
1947         debugger = GetGlobalDebugger()
1948  
1949         if debugger:
1950   
1951             debugger.SetTraceForFrameAndParents(
1952                 GetFrame(), also_add_to_passed_frame=True, overwrite_prev_trace=True, dispatch_func=lambda *args:None)
1953             debugger.exiting()
1954   
1955             killAllPydevThreads()
1956
1957         connected = False
1958
1959 class Dispatcher(object):
1960     def __init__(self):
1961         self.port = None
1962
1963     def connect(self, host, port):
1964         self.host  = host
1965         self.port = port
1966         self.client = StartClient(self.host, self.port)
1967         self.reader = DispatchReader(self)
1968         self.reader.dontTraceMe = False #we run reader in the same thread so we don't want to loose tracing
1969         self.reader.run()
1970
1971     def close(self):
1972         try:
1973             self.reader.doKillPydevThread()
1974         except :
1975             pass
1976
1977 class DispatchReader(ReaderThread):
1978     def __init__(self, dispatcher):
1979         self.dispatcher = dispatcher
1980         ReaderThread.__init__(self, self.dispatcher.client)
1981
1982     def OnRun(self):
1983         dummy_thread = threading.currentThread()
1984         dummy_thread.is_pydev_daemon_thread = False
1985         return ReaderThread.OnRun(self)
1986         
1987     def handleExcept(self):
1988         ReaderThread.handleExcept(self)
1989
1990     def processCommand(self, cmd_id, seq, text):
1991         if cmd_id == 99:
1992             self.dispatcher.port = int(text)
1993             self.killReceived = True
1994
1995
1996 DISPATCH_APPROACH_NEW_CONNECTION = 1 # Used by PyDev
1997 DISPATCH_APPROACH_EXISTING_CONNECTION = 2 # Used by PyCharm
1998 DISPATCH_APPROACH = DISPATCH_APPROACH_NEW_CONNECTION
1999
2000 def dispatch():
2001     setup = SetupHolder.setup
2002     host = setup['client']
2003     port = setup['port']
2004     if DISPATCH_APPROACH == DISPATCH_APPROACH_EXISTING_CONNECTION:
2005         dispatcher = Dispatcher()
2006         try:
2007             dispatcher.connect(host, port)
2008             port = dispatcher.port
2009         finally:
2010             dispatcher.close()
2011     return host, port
2012
2013
2014 def settrace_forked():
2015     '''
2016     When creating a fork from a process in the debugger, we need to reset the whole debugger environment!
2017     '''
2018     host, port = dispatch()
2019
2020     import pydevd_tracing
2021     pydevd_tracing.RestoreSysSetTraceFunc()
2022
2023     if port is not None:
2024         global connected
2025         connected = False
2026
2027         CustomFramesContainerInit()
2028
2029         settrace(
2030             host,
2031             port=port,
2032             suspend=False,
2033             trace_only_current_thread=False,
2034             overwrite_prev_trace=True,
2035             patch_multiprocessing=True,
2036             )
2037
2038 #=======================================================================================================================
2039 # SetupHolder
2040 #=======================================================================================================================
2041 class SetupHolder:
2042
2043     setup = None
2044
2045
2046 #=======================================================================================================================
2047 # main
2048 #=======================================================================================================================
2049 if __name__ == '__main__':
2050     
2051     # parse the command line. --file is our last argument that is required
2052     try:
2053         sys.original_argv = sys.argv[:]
2054         setup = processCommandLine(sys.argv)
2055         SetupHolder.setup = setup
2056     except ValueError:
2057         traceback.print_exc()
2058         usage(1)
2059
2060     if setup['print-in-debugger-startup']:
2061         try:
2062             pid = ' (pid: %s)' % os.getpid()
2063         except:
2064             pid = ''
2065         sys.stderr.write("pydev debugger: starting%s\n" % pid)
2066
2067     fix_getpass.fixGetpass()
2068
2069     pydev_log.debug("Executing file %s" % setup['file'])
2070     pydev_log.debug("arguments: %s"% str(sys.argv))
2071
2072
2073     pydevd_vm_type.SetupType(setup.get('vm_type', None))
2074
2075     if os.getenv('PYCHARM_DEBUG'):
2076         set_debug(setup)
2077
2078     DebugInfoHolder.DEBUG_RECORD_SOCKET_READS = setup.get('DEBUG_RECORD_SOCKET_READS', False)
2079     DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS = setup.get('DEBUG_TRACE_BREAKPOINTS', -1)
2080     DebugInfoHolder.DEBUG_TRACE_LEVEL = setup.get('DEBUG_TRACE_LEVEL', -1)
2081
2082     port = setup['port']
2083     host = setup['client']
2084     f = setup['file']
2085     fix_app_engine_debug = False
2086
2087
2088     try:
2089         import pydev_monkey
2090     except:
2091         pass #Not usable on jython 2.1
2092     else:
2093         if setup['multiprocess']: # PyDev
2094             pydev_monkey.patch_new_process_functions()
2095
2096         elif setup['multiproc']: # PyCharm
2097             pydev_log.debug("Started in multiproc mode\n")
2098             # Note: we're not inside method, so, no need for 'global'
2099             DISPATCH_APPROACH = DISPATCH_APPROACH_EXISTING_CONNECTION
2100
2101             dispatcher = Dispatcher()
2102             try:
2103                 dispatcher.connect(host, port)
2104                 if dispatcher.port is not None:
2105                     port = dispatcher.port
2106                     pydev_log.debug("Received port %d\n" %port)
2107                     pydev_log.info("pydev debugger: process %d is connecting\n"% os.getpid())
2108
2109                     try:
2110                         pydev_monkey.patch_new_process_functions()
2111                     except:
2112                         pydev_log.error("Error patching process functions\n")
2113                         traceback.print_exc()
2114                 else:
2115                     pydev_log.error("pydev debugger: couldn't get port for new debug process\n")
2116             finally:
2117                 dispatcher.close()
2118         else:
2119             pydev_log.info("pydev debugger: starting\n")
2120
2121             try:
2122                 pydev_monkey.patch_new_process_functions_with_warning()
2123             except:
2124                 pydev_log.error("Error patching process functions\n")
2125                 traceback.print_exc()
2126
2127             # Only do this patching if we're not running with multiprocess turned on.
2128             if f.find('dev_appserver.py') != -1:
2129                 if os.path.basename(f).startswith('dev_appserver.py'):
2130                     appserver_dir = os.path.dirname(f)
2131                     version_file = os.path.join(appserver_dir, 'VERSION')
2132                     if os.path.exists(version_file):
2133                         try:
2134                             stream = open(version_file, 'r')
2135                             try:
2136                                 for line in stream.read().splitlines():
2137                                     line = line.strip()
2138                                     if line.startswith('release:'):
2139                                         line = line[8:].strip()
2140                                         version = line.replace('"', '')
2141                                         version = version.split('.')
2142                                         if int(version[0]) > 1:
2143                                             fix_app_engine_debug = True
2144
2145                                         elif int(version[0]) == 1:
2146                                             if int(version[1]) >= 7:
2147                                                 # Only fix from 1.7 onwards
2148                                                 fix_app_engine_debug = True
2149                                         break
2150                             finally:
2151                                 stream.close()
2152                         except:
2153                             traceback.print_exc()
2154
2155     try:
2156         # In the default run (i.e.: run directly on debug mode), we try to patch stackless as soon as possible
2157         # on a run where we have a remote debug, we may have to be more careful because patching stackless means
2158         # that if the user already had a stackless.set_schedule_callback installed, he'd loose it and would need
2159         # to call it again (because stackless provides no way of getting the last function which was registered
2160         # in set_schedule_callback).
2161         #
2162         # So, ideally, if there's an application using stackless and the application wants to use the remote debugger
2163         # and benefit from stackless debugging, the application itself must call:
2164         #
2165         # import pydevd_stackless
2166         # pydevd_stackless.patch_stackless()
2167         #
2168         # itself to be able to benefit from seeing the tasklets created before the remote debugger is attached.
2169         import pydevd_stackless
2170         pydevd_stackless.patch_stackless()
2171     except:
2172         pass  # It's ok not having stackless there...
2173
2174     debugger = PyDB()
2175
2176     if fix_app_engine_debug:
2177         sys.stderr.write("pydev debugger: google app engine integration enabled\n")
2178         curr_dir = os.path.dirname(__file__)
2179         app_engine_startup_file = os.path.join(curr_dir, 'pydev_app_engine_debug_startup.py')
2180
2181         sys.argv.insert(1, '--python_startup_script=' + app_engine_startup_file)
2182         import json
2183         setup['pydevd'] = __file__
2184         sys.argv.insert(2, '--python_startup_args=%s' % json.dumps(setup),)
2185         sys.argv.insert(3, '--automatic_restart=no')
2186         sys.argv.insert(4, '--max_module_instances=1')
2187
2188         # Run the dev_appserver
2189         debugger.run(setup['file'], None, None, set_trace=False)
2190     else:
2191         # as to get here all our imports are already resolved, the psyco module can be
2192         # changed and we'll still get the speedups in the debugger, as those functions
2193         # are already compiled at this time.
2194         try:
2195             import psyco
2196         except ImportError:
2197             if hasattr(sys, 'exc_clear'):  # jython does not have it
2198                 sys.exc_clear()  # don't keep the traceback -- clients don't want to see it
2199             pass  # that's ok, no need to mock psyco if it's not available anyways
2200         else:
2201             # if it's available, let's change it for a stub (pydev already made use of it)
2202             import pydevd_psyco_stub
2203             sys.modules['psyco'] = pydevd_psyco_stub
2204
2205         if setup['save-signatures']:
2206             if pydevd_vm_type.GetVmType() == pydevd_vm_type.PydevdVmType.JYTHON:
2207                 sys.stderr.write("Collecting run-time type information is not supported for Jython\n")
2208             else:
2209                 # Only import it if we're going to use it!
2210                 from pydevd_signature import SignatureFactory
2211                 debugger.signature_factory = SignatureFactory()
2212
2213         try:
2214             debugger.connect(host, port)
2215         except:
2216             sys.stderr.write("Could not connect to %s: %s\n" % (host, port))
2217             traceback.print_exc()
2218             sys.exit(1)
2219
2220         connected = True  # Mark that we're connected when started from inside ide.
2221
2222         globals = debugger.run(setup['file'], None, None)
2223
2224         if setup['cmd-line']:
2225             debugger.wait_for_commands(globals)
2226
2227