Fixed an issue when Ctrl+C(SIGINT) terminates debugging session instead of halting // Resolve #2733

This commit is contained in:
Ivan Kravets
2019-07-04 17:47:26 +03:00
parent d9b6842b6a
commit caf5159002
4 changed files with 23 additions and 1 deletions

View File

@ -15,6 +15,7 @@
import json import json
import os import os
import re import re
import signal
import time import time
from hashlib import sha1 from hashlib import sha1
from os.path import abspath, basename, dirname, isdir, join, splitext 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: if b"-exec-continue" in data:
self._target_is_run = True self._target_is_run = True
if b"-gdb-exit" in data or data.strip() in (b"q", b"quit"): 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(b"pio_reset_target\n")
self.transport.write(data) self.transport.write(data)

View File

@ -16,6 +16,7 @@
# pylint: disable=too-many-locals, too-many-branches # pylint: disable=too-many-locals, too-many-branches
import os import os
import signal
from os.path import isfile, join from os.path import isfile, join
import click 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 = GDBClient(project_dir, __unprocessed, debug_options, env_options)
client.spawn(configuration['gdb_path'], configuration['prog_path']) client.spawn(configuration['gdb_path'], configuration['prog_path'])
signal.signal(signal.SIGINT, lambda *args, **kwargs: None)
reactor.run() reactor.run()
return True return True

View File

@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import signal
import click import click
from twisted.internet import protocol # pylint: disable=import-error 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: with open(LOG_FILE, "ab") as fp:
fp.write(data) fp.write(data)
click.echo(data, nl=False, err=True) click.echo(data, nl=False, err=True)
@staticmethod
def processEnded(_):
# Allow terminating via SIGINT/CTRL+C
signal.signal(signal.SIGINT, signal.default_int_handler)

View File

@ -15,6 +15,7 @@
import os import os
from os.path import isdir, isfile, join 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 twisted.internet import reactor # pylint: disable=import-error
from platformio import exception, util from platformio import exception, util
@ -31,6 +32,7 @@ class DebugServer(BaseProcess):
self._debug_port = None self._debug_port = None
self._transport = None self._transport = None
self._process_ended = False
def spawn(self, patterns): # pylint: disable=too-many-branches def spawn(self, patterns): # pylint: disable=too-many-branches
systype = util.get_systype() systype = util.get_systype()
@ -108,6 +110,14 @@ class DebugServer(BaseProcess):
def get_debug_port(self): def get_debug_port(self):
return self._debug_port return self._debug_port
def processEnded(self, reason):
self._process_ended = True
super(DebugServer, self).processEnded(reason)
def terminate(self): def terminate(self):
if self._transport: if self._process_ended or not self._transport:
return
try:
self._transport.signalProcess("KILL") self._transport.signalProcess("KILL")
except (OSError, error.ProcessExitedAlready):
pass