From caf51590029cd45628c21249e40a99cdaa1fdedd Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Thu, 4 Jul 2019 17:47:26 +0300 Subject: [PATCH] Fixed an issue when Ctrl+C(SIGINT) terminates debugging session instead of halting // Resolve #2733 --- platformio/commands/debug/client.py | 3 +++ platformio/commands/debug/command.py | 2 ++ platformio/commands/debug/process.py | 7 +++++++ platformio/commands/debug/server.py | 12 +++++++++++- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/platformio/commands/debug/client.py b/platformio/commands/debug/client.py index 9b208a48..f6d403bb 100644 --- a/platformio/commands/debug/client.py +++ b/platformio/commands/debug/client.py @@ -15,6 +15,7 @@ import json import os import re +import signal import time from hashlib import sha1 from os.path import abspath, basename, dirname, isdir, join, splitext @@ -188,6 +189,8 @@ class GDBClient(BaseProcess): # pylint: disable=too-many-instance-attributes 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"): + # Allow terminating via SIGINT/CTRL+C + signal.signal(signal.SIGINT, signal.default_int_handler) self.transport.write(b"pio_reset_target\n") self.transport.write(data) diff --git a/platformio/commands/debug/command.py b/platformio/commands/debug/command.py index 8599a962..14c4f665 100644 --- a/platformio/commands/debug/command.py +++ b/platformio/commands/debug/command.py @@ -16,6 +16,7 @@ # pylint: disable=too-many-locals, too-many-branches import os +import signal from os.path import isfile, join import click @@ -146,6 +147,7 @@ def cli(ctx, project_dir, project_conf, environment, verbose, interface, client = GDBClient(project_dir, __unprocessed, debug_options, env_options) client.spawn(configuration['gdb_path'], configuration['prog_path']) + signal.signal(signal.SIGINT, lambda *args, **kwargs: None) reactor.run() return True diff --git a/platformio/commands/debug/process.py b/platformio/commands/debug/process.py index a9064492..98c7cc1a 100644 --- a/platformio/commands/debug/process.py +++ b/platformio/commands/debug/process.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import signal + import click from twisted.internet import protocol # pylint: disable=import-error @@ -71,3 +73,8 @@ class BaseProcess(protocol.ProcessProtocol, object): with open(LOG_FILE, "ab") as fp: fp.write(data) click.echo(data, nl=False, err=True) + + @staticmethod + def processEnded(_): + # Allow terminating via SIGINT/CTRL+C + signal.signal(signal.SIGINT, signal.default_int_handler) diff --git a/platformio/commands/debug/server.py b/platformio/commands/debug/server.py index 6d81585e..83bba340 100644 --- a/platformio/commands/debug/server.py +++ b/platformio/commands/debug/server.py @@ -15,6 +15,7 @@ import os from os.path import isdir, isfile, join +from twisted.internet import error # pylint: disable=import-error from twisted.internet import reactor # pylint: disable=import-error from platformio import exception, util @@ -31,6 +32,7 @@ class DebugServer(BaseProcess): self._debug_port = None self._transport = None + self._process_ended = False def spawn(self, patterns): # pylint: disable=too-many-branches systype = util.get_systype() @@ -108,6 +110,14 @@ class DebugServer(BaseProcess): def get_debug_port(self): return self._debug_port + def processEnded(self, reason): + self._process_ended = True + super(DebugServer, self).processEnded(reason) + def terminate(self): - if self._transport: + if self._process_ended or not self._transport: + return + try: self._transport.signalProcess("KILL") + except (OSError, error.ProcessExitedAlready): + pass