| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  | # Copyright (c) 2014-present PlatformIO <contact@platformio.org> | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  | # you may not use this file except in compliance with the License. | 
					
						
							|  |  |  | # You may obtain a copy of the License at | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #    http://www.apache.org/licenses/LICENSE-2.0 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  | # distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  | # See the License for the specific language governing permissions and | 
					
						
							|  |  |  | # limitations under the License. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import re | 
					
						
							| 
									
										
										
										
											2019-07-04 17:47:26 +03:00
										 |  |  | import signal | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  | import time | 
					
						
							|  |  |  | from hashlib import sha1 | 
					
						
							| 
									
										
										
										
											2019-11-15 16:02:15 +02:00
										 |  |  | from os.path import basename, dirname, isdir, join, realpath, splitext | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  | from tempfile import mkdtemp | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-10 13:00:53 +03:00
										 |  |  | from twisted.internet import protocol  # pylint: disable=import-error | 
					
						
							|  |  |  | from twisted.internet import reactor  # pylint: disable=import-error | 
					
						
							|  |  |  | from twisted.internet import stdio  # pylint: disable=import-error | 
					
						
							|  |  |  | from twisted.internet import task  # pylint: disable=import-error | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-28 16:15:54 +02:00
										 |  |  | from platformio import app, fs, proc, telemetry, util | 
					
						
							| 
									
										
										
										
											2019-10-23 16:05:27 +03:00
										 |  |  | from platformio.commands.debug import helpers, initcfgs | 
					
						
							| 
									
										
										
										
											2019-11-28 16:15:54 +02:00
										 |  |  | from platformio.commands.debug.exception import DebugInvalidOptionsError | 
					
						
							| 
									
										
										
										
											2019-10-23 16:05:27 +03:00
										 |  |  | from platformio.commands.debug.process import BaseProcess | 
					
						
							|  |  |  | from platformio.commands.debug.server import DebugServer | 
					
						
							| 
									
										
										
										
											2019-11-06 22:30:58 +02:00
										 |  |  | from platformio.compat import hashlib_encode_data, is_bytes | 
					
						
							| 
									
										
										
										
											2019-05-27 22:25:22 +03:00
										 |  |  | from platformio.project.helpers import get_project_cache_dir | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | LOG_FILE = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class GDBClient(BaseProcess):  # pylint: disable=too-many-instance-attributes | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PIO_SRC_NAME = ".pioinit" | 
					
						
							|  |  |  |     INIT_COMPLETED_BANNER = "PlatformIO: Initialization completed" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, project_dir, args, debug_options, env_options): | 
					
						
							|  |  |  |         self.project_dir = project_dir | 
					
						
							|  |  |  |         self.args = list(args) | 
					
						
							|  |  |  |         self.debug_options = debug_options | 
					
						
							|  |  |  |         self.env_options = env_options | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self._debug_server = DebugServer(debug_options, env_options) | 
					
						
							|  |  |  |         self._session_id = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 22:25:22 +03:00
										 |  |  |         if not isdir(get_project_cache_dir()): | 
					
						
							|  |  |  |             os.makedirs(get_project_cache_dir()) | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         self._gdbsrc_dir = mkdtemp(dir=get_project_cache_dir(), prefix=".piodebug-") | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self._target_is_run = False | 
					
						
							|  |  |  |         self._last_server_activity = 0 | 
					
						
							|  |  |  |         self._auto_continue_timer = None | 
					
						
							| 
									
										
										
										
											2019-11-28 16:15:54 +02:00
										 |  |  |         self._errors_buffer = b"" | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def spawn(self, gdb_path, prog_path): | 
					
						
							|  |  |  |         session_hash = gdb_path + prog_path | 
					
						
							| 
									
										
										
										
											2019-06-03 13:30:35 +03:00
										 |  |  |         self._session_id = sha1(hashlib_encode_data(session_hash)).hexdigest() | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         self._kill_previous_session() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         patterns = { | 
					
						
							| 
									
										
										
										
											2019-07-15 14:20:14 +03:00
										 |  |  |             "PROJECT_DIR": self.project_dir, | 
					
						
							|  |  |  |             "PROG_PATH": prog_path, | 
					
						
							|  |  |  |             "PROG_DIR": dirname(prog_path), | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |             "PROG_NAME": basename(splitext(prog_path)[0]), | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |             "DEBUG_PORT": self.debug_options["port"], | 
					
						
							|  |  |  |             "UPLOAD_PROTOCOL": self.debug_options["upload_protocol"], | 
					
						
							|  |  |  |             "INIT_BREAK": self.debug_options["init_break"] or "", | 
					
						
							|  |  |  |             "LOAD_CMDS": "\n".join(self.debug_options["load_cmds"] or []), | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self._debug_server.spawn(patterns) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         if not patterns["DEBUG_PORT"]: | 
					
						
							|  |  |  |             patterns["DEBUG_PORT"] = self._debug_server.get_debug_port() | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         self.generate_pioinit(self._gdbsrc_dir, patterns) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # start GDB client | 
					
						
							|  |  |  |         args = [ | 
					
						
							|  |  |  |             "piogdb", | 
					
						
							|  |  |  |             "-q", | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |             "--directory", | 
					
						
							|  |  |  |             self._gdbsrc_dir, | 
					
						
							|  |  |  |             "--directory", | 
					
						
							|  |  |  |             self.project_dir, | 
					
						
							|  |  |  |             "-l", | 
					
						
							|  |  |  |             "10", | 
					
						
							| 
									
										
										
										
											2019-09-27 14:13:53 +03:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         args.extend(self.args) | 
					
						
							|  |  |  |         if not gdb_path: | 
					
						
							| 
									
										
										
										
											2019-11-28 16:15:54 +02:00
										 |  |  |             raise DebugInvalidOptionsError("GDB client is not configured") | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         gdb_data_dir = self._get_data_dir(gdb_path) | 
					
						
							|  |  |  |         if gdb_data_dir: | 
					
						
							|  |  |  |             args.extend(["--data-directory", gdb_data_dir]) | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         args.append(patterns["PROG_PATH"]) | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         return reactor.spawnProcess( | 
					
						
							|  |  |  |             self, gdb_path, args, path=self.project_dir, env=os.environ | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def _get_data_dir(gdb_path): | 
					
						
							|  |  |  |         if "msp430" in gdb_path: | 
					
						
							|  |  |  |             return None | 
					
						
							| 
									
										
										
										
											2019-11-15 16:02:15 +02:00
										 |  |  |         gdb_data_dir = realpath(join(dirname(gdb_path), "..", "share", "gdb")) | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         return gdb_data_dir if isdir(gdb_data_dir) else None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def generate_pioinit(self, dst_dir, patterns): | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         server_exe = ( | 
					
						
							|  |  |  |             (self.debug_options.get("server") or {}).get("executable", "").lower() | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         if "jlink" in server_exe: | 
					
						
							|  |  |  |             cfg = initcfgs.GDB_JLINK_INIT_CONFIG | 
					
						
							|  |  |  |         elif "st-util" in server_exe: | 
					
						
							|  |  |  |             cfg = initcfgs.GDB_STUTIL_INIT_CONFIG | 
					
						
							|  |  |  |         elif "mspdebug" in server_exe: | 
					
						
							| 
									
										
										
										
											2019-04-19 19:58:34 +03:00
										 |  |  |             cfg = initcfgs.GDB_MSPDEBUG_INIT_CONFIG | 
					
						
							| 
									
										
										
										
											2019-06-27 15:07:13 +03:00
										 |  |  |         elif "qemu" in server_exe: | 
					
						
							|  |  |  |             cfg = initcfgs.GDB_QEMU_INIT_CONFIG | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         elif self.debug_options["require_debug_port"]: | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |             cfg = initcfgs.GDB_BLACKMAGIC_INIT_CONFIG | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             cfg = initcfgs.GDB_DEFAULT_INIT_CONFIG | 
					
						
							|  |  |  |         commands = cfg.split("\n") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         if self.debug_options["init_cmds"]: | 
					
						
							|  |  |  |             commands = self.debug_options["init_cmds"] | 
					
						
							|  |  |  |         commands.extend(self.debug_options["extra_cmds"]) | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-06 12:20:42 +02:00
										 |  |  |         if not any("define pio_reset_run_target" in cmd for cmd in commands): | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |             commands = [ | 
					
						
							| 
									
										
										
										
											2019-11-06 12:20:42 +02:00
										 |  |  |                 "define pio_reset_run_target", | 
					
						
							|  |  |  |                 "   echo Warning! Undefined pio_reset_run_target command\\n", | 
					
						
							|  |  |  |                 "   monitor reset", | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |                 "end", | 
					
						
							| 
									
										
										
										
											2019-09-27 14:13:53 +03:00
										 |  |  |             ] + commands | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         if not any("define pio_reset_halt_target" in cmd for cmd in commands): | 
					
						
							|  |  |  |             commands = [ | 
					
						
							|  |  |  |                 "define pio_reset_halt_target", | 
					
						
							|  |  |  |                 "   echo Warning! Undefined pio_reset_halt_target command\\n", | 
					
						
							| 
									
										
										
										
											2019-11-06 12:20:42 +02:00
										 |  |  |                 "   monitor reset halt", | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |                 "end", | 
					
						
							| 
									
										
										
										
											2019-09-27 14:13:53 +03:00
										 |  |  |             ] + commands | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         if not any("define pio_restart_target" in cmd for cmd in commands): | 
					
						
							|  |  |  |             commands += [ | 
					
						
							|  |  |  |                 "define pio_restart_target", | 
					
						
							|  |  |  |                 "   pio_reset_halt_target", | 
					
						
							|  |  |  |                 "   $INIT_BREAK", | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |                 "   %s" % ("continue" if patterns["INIT_BREAK"] else "next"), | 
					
						
							|  |  |  |                 "end", | 
					
						
							| 
									
										
										
										
											2019-09-27 14:13:53 +03:00
										 |  |  |             ] | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         banner = [ | 
					
						
							| 
									
										
										
										
											2019-05-30 22:26:42 +03:00
										 |  |  |             "echo PlatformIO Unified Debugger -> http://bit.ly/pio-debug\\n", | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |             "echo PlatformIO: debug_tool = %s\\n" % self.debug_options["tool"], | 
					
						
							|  |  |  |             "echo PlatformIO: Initializing remote target...\\n", | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         ] | 
					
						
							|  |  |  |         footer = ["echo %s\\n" % self.INIT_COMPLETED_BANNER] | 
					
						
							|  |  |  |         commands = banner + commands + footer | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with open(join(dst_dir, self.PIO_SRC_NAME), "w") as fp: | 
					
						
							|  |  |  |             fp.write("\n".join(self.apply_patterns(commands, patterns))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def connectionMade(self): | 
					
						
							|  |  |  |         self._lock_session(self.transport.pid) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         p = protocol.Protocol() | 
					
						
							|  |  |  |         p.dataReceived = self.onStdInData | 
					
						
							|  |  |  |         stdio.StandardIO(p) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def onStdInData(self, data): | 
					
						
							|  |  |  |         if LOG_FILE: | 
					
						
							|  |  |  |             with open(LOG_FILE, "ab") as fp: | 
					
						
							|  |  |  |                 fp.write(data) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-27 13:38:46 +03:00
										 |  |  |         self._last_server_activity = time.time() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         if b"-exec-run" in data: | 
					
						
							|  |  |  |             if self._target_is_run: | 
					
						
							|  |  |  |                 token, _ = data.split(b"-", 1) | 
					
						
							|  |  |  |                 self.outReceived(token + b"^running\n") | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             data = data.replace(b"-exec-run", b"-exec-continue") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if b"-exec-continue" in data: | 
					
						
							|  |  |  |             self._target_is_run = True | 
					
						
							|  |  |  |         if b"-gdb-exit" in data or data.strip() in (b"q", b"quit"): | 
					
						
							| 
									
										
										
										
											2019-07-04 17:47:26 +03:00
										 |  |  |             # Allow terminating via SIGINT/CTRL+C | 
					
						
							|  |  |  |             signal.signal(signal.SIGINT, signal.default_int_handler) | 
					
						
							| 
									
										
										
										
											2019-11-06 12:20:42 +02:00
										 |  |  |             self.transport.write(b"pio_reset_run_target\n") | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         self.transport.write(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def processEnded(self, reason):  # pylint: disable=unused-argument | 
					
						
							|  |  |  |         self._unlock_session() | 
					
						
							|  |  |  |         if self._gdbsrc_dir and isdir(self._gdbsrc_dir): | 
					
						
							| 
									
										
										
										
											2019-08-12 19:44:37 +03:00
										 |  |  |             fs.rmtree(self._gdbsrc_dir) | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         if self._debug_server: | 
					
						
							|  |  |  |             self._debug_server.terminate() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         reactor.stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def outReceived(self, data): | 
					
						
							| 
									
										
										
										
											2019-06-27 13:38:46 +03:00
										 |  |  |         if LOG_FILE: | 
					
						
							|  |  |  |             with open(LOG_FILE, "ab") as fp: | 
					
						
							|  |  |  |                 fp.write(data) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         self._last_server_activity = time.time() | 
					
						
							|  |  |  |         super(GDBClient, self).outReceived(data) | 
					
						
							|  |  |  |         self._handle_error(data) | 
					
						
							|  |  |  |         # go to init break automatically | 
					
						
							|  |  |  |         if self.INIT_COMPLETED_BANNER.encode() in data: | 
					
						
							| 
									
										
										
										
											2019-11-28 16:15:54 +02:00
										 |  |  |             telemetry.send_event( | 
					
						
							|  |  |  |                 "Debug", "Started", telemetry.encode_run_environment(self.env_options) | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |             self._auto_continue_timer = task.LoopingCall(self._auto_exec_continue) | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |             self._auto_continue_timer.start(0.1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def errReceived(self, data): | 
					
						
							|  |  |  |         super(GDBClient, self).errReceived(data) | 
					
						
							|  |  |  |         self._handle_error(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def console_log(self, msg): | 
					
						
							| 
									
										
										
										
											2019-11-06 22:30:58 +02:00
										 |  |  |         if helpers.is_gdbmi_mode(): | 
					
						
							|  |  |  |             msg = helpers.escape_gdbmi_stream("~", msg) | 
					
						
							|  |  |  |         self.outReceived(msg if is_bytes(msg) else msg.encode()) | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _auto_exec_continue(self): | 
					
						
							|  |  |  |         auto_exec_delay = 0.5  # in seconds | 
					
						
							|  |  |  |         if self._last_server_activity > (time.time() - auto_exec_delay): | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         if self._auto_continue_timer: | 
					
						
							|  |  |  |             self._auto_continue_timer.stop() | 
					
						
							|  |  |  |         self._auto_continue_timer = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         if not self.debug_options["init_break"] or self._target_is_run: | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |             return | 
					
						
							|  |  |  |         self.console_log( | 
					
						
							| 
									
										
										
										
											2019-11-06 22:30:58 +02:00
										 |  |  |             "PlatformIO: Resume the execution to `debug_init_break = %s`\n" | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |             % self.debug_options["init_break"] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.console_log( | 
					
						
							| 
									
										
										
										
											2019-11-06 22:30:58 +02:00
										 |  |  |             "PlatformIO: More configuration options -> http://bit.ly/pio-debug\n" | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         ) | 
					
						
							|  |  |  |         self.transport.write( | 
					
						
							| 
									
										
										
										
											2019-11-06 22:30:58 +02:00
										 |  |  |             b"0-exec-continue\n" if helpers.is_gdbmi_mode() else b"continue\n" | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         self._target_is_run = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _handle_error(self, data): | 
					
						
							| 
									
										
										
										
											2019-11-28 16:15:54 +02:00
										 |  |  |         self._errors_buffer += data | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         if self.PIO_SRC_NAME.encode() not in data or b"Error in sourced" not in data: | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-11-28 16:15:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         last_erros = self._errors_buffer.decode() | 
					
						
							|  |  |  |         last_erros = " ".join(reversed(last_erros.split("\n"))) | 
					
						
							|  |  |  |         last_erros = re.sub(r'((~|&)"|\\n\"|\\t)', " ", last_erros, flags=re.M) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         err = "%s -> %s" % ( | 
					
						
							|  |  |  |             telemetry.encode_run_environment(self.env_options), | 
					
						
							|  |  |  |             last_erros, | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-11-28 16:15:54 +02:00
										 |  |  |         telemetry.send_exception("DebugInitError: %s" % err, is_fatal=True) | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         self.transport.loseConnection() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _kill_previous_session(self): | 
					
						
							|  |  |  |         assert self._session_id | 
					
						
							|  |  |  |         pid = None | 
					
						
							|  |  |  |         with app.ContentCache() as cc: | 
					
						
							|  |  |  |             pid = cc.get(self._session_id) | 
					
						
							|  |  |  |             cc.delete(self._session_id) | 
					
						
							|  |  |  |         if not pid: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         if "windows" in util.get_systype(): | 
					
						
							|  |  |  |             kill = ["Taskkill", "/PID", pid, "/F"] | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             kill = ["kill", pid] | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2019-08-12 19:44:37 +03:00
										 |  |  |             proc.exec_command(kill) | 
					
						
							| 
									
										
										
										
											2019-04-19 19:56:16 +03:00
										 |  |  |         except:  # pylint: disable=bare-except | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _lock_session(self, pid): | 
					
						
							|  |  |  |         if not self._session_id: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         with app.ContentCache() as cc: | 
					
						
							|  |  |  |             cc.set(self._session_id, str(pid), "1h") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _unlock_session(self): | 
					
						
							|  |  |  |         if not self._session_id: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         with app.ContentCache() as cc: | 
					
						
							|  |  |  |             cc.delete(self._session_id) |