85 lines
2.6 KiB
Python
85 lines
2.6 KiB
Python
#!/usr/bin/python
|
|
import os
|
|
import select
|
|
import time
|
|
import subprocess
|
|
|
|
gdb_process = None
|
|
|
|
def __write_to_gdb(msg):
|
|
gdb_process.stdin.write(msg.encode('utf-8'))
|
|
gdb_process.stdin.write(b'\n')
|
|
|
|
def start_gdb(gdb_binary):
|
|
global gdb_process
|
|
try:
|
|
gdb_process = subprocess.Popen([gdb_binary, '-q', '--nh', '--nx'], bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
__write_to_gdb(r'set prompt (gdb)\n')
|
|
gdb_process.stdout.readline()
|
|
return 'OK'
|
|
except OSError:
|
|
return 'FAIL'
|
|
|
|
def command_gdb(cmd, timeout=None):
|
|
async_command_gdb(cmd)
|
|
return read_async_command_output(int(timeout) if timeout else None)
|
|
|
|
def async_command_gdb(cmd):
|
|
__write_to_gdb(cmd)
|
|
|
|
def read_async_command_output(timeout=None):
|
|
""" timeout in seconds """
|
|
result = ''
|
|
current_line = ''
|
|
poll_obj = select.poll()
|
|
poll_obj.register(gdb_process.stdout.fileno(), select.POLLIN)
|
|
|
|
timestamp_before = time.time()
|
|
timestamp_timeout = timestamp_before + (int(timeout) if timeout else 0)
|
|
while True:
|
|
if timeout and time.time() > timestamp_timeout:
|
|
raise Exception('[timeout occurred] current buffer is:\n{}\n{}'.format(result, current_line))
|
|
poll_results = poll_obj.poll(1000)
|
|
for (fd, event) in poll_results:
|
|
if fd == gdb_process.stdout.fileno():
|
|
c = gdb_process.stdout.read(1).decode('utf-8')
|
|
|
|
if c == '\n':
|
|
if current_line.strip() == '(gdb)':
|
|
return result
|
|
else:
|
|
result += current_line + '\n'
|
|
current_line = ''
|
|
else:
|
|
current_line += c
|
|
|
|
def read_async_command_error(timeout=None, throw_exception=True):
|
|
""" timeout in seconds """
|
|
current_error = ''
|
|
poll_obj = select.poll()
|
|
poll_obj.register(gdb_process.stderr, select.POLLIN)
|
|
|
|
timestamp_before = time.time()
|
|
timestamp_timeout = timestamp_before + (int(timeout) if timeout else 0)
|
|
while True:
|
|
if timeout and time.time() > timestamp_timeout:
|
|
if throw_exception:
|
|
raise Exception('[timeout occurred]')
|
|
return ""
|
|
poll_results = poll_obj.poll(1000)
|
|
for (fd, event) in poll_results:
|
|
if fd == gdb_process.stderr.fileno():
|
|
c = gdb_process.stderr.read(1).decode('utf-8')
|
|
|
|
if c == '\n':
|
|
return current_error + '\n'
|
|
else:
|
|
current_error += c
|
|
|
|
def send_signal_to_gdb(sig):
|
|
os.kill(gdb_process.pid, int(sig))
|
|
|
|
def stop_gdb():
|
|
gdb_process.terminate()
|
|
|