Мне трудно восстановить ошибку, и я надеюсь использовать python GDB script
, чтобы остановить процесс при обнаружении ошибки (я буду запускать его в режиме отладки, пока ошибка не будет восстановлена). В отношении блуждающих символов, видимых из snprintf .
В настоящее время я создал скрипт, который может создавать break-point
и параллельно читать терминал serial
, чтобы обнаружить ошибку в строке. Вот сценарий:
from __future__ import print_function
import serial
import pandas as pd
import argparse
import io
import time
import ast
import sys
import signal
import threading
class Serial_Port():
def __init__(self, port_number, baud_rate):
self.ser = serial.Serial(port_number, baud_rate, timeout=10)
self.ser_io = io.TextIOWrapper(io.BufferedRWPair(self.ser, self.ser, 1), newline = '\r', line_buffering = True)
self.data_count = 0
self.data_times = 0
self.data_succ = 0
self.ifPrint = False
def read(self):
raw_line = self.ser_io.readline()
raw_line = raw_line.strip("\x00")
raw_line = raw_line.strip("\r\n")
if self.ifPrint == True:
fptr.write(raw_line)
else:
self.data_times +=1
# Print the current status of string test
to_write = "Loop: %d Read Count: %d Successful: %d" % (self.data_times, self.data_count, self.data_succ)
fptr.write(to_write)
fptr.write("\n")
if "[[" in raw_line:
self.data_count += 1
self.parse(raw_line)
#Flush all the data before returning
fptr.flush()
def parse(self, gnss):
try:
#if we are able to convert literal and a DF made
# we'll assume the data received is valid
gnss = ast.literal_eval(gnss)
df = pd.DataFrame(gnss)
self.data_succ += 1
except KeyboardInterrupt:
self.ser.flush()
self.ser.close()
sys.exit(0)
except:
fptr.write(gnss)
fptr.write("\n")
fptr.flush()
def close(self, frame, andsomething):
self.ser.flush()
self.ser.close()
sys.exit(0)
class DebugPrintingBreakpoint(gdb.Breakpoint):
debugging_IDs = frozenset({37, 153, 420})
def stop(self):
top = gdb.newest_frame()
someVector = top.read_var('aVectorVar')
# Access the begin() & end() pointer of std::vector in GNU Standard C++ lib
first = someVector['_M_impl']['_M_start']
last = someVector['_M_impl']['_M_finish']
values = []
while first != last:
values.append(int(first.dereference()['intID']))
first = first + 1
if not set(values) & debugging_IDs:
return False # skip: none of the items we're looking for can be found by ID in the vector on the stack
print("Found other accompanying IDs: {}".format(values))
return True # drop to gdb's prompt
class MyThread_serial(threading.Thread):
def run(self):
while True:
time.sleep(1)#sleep for 1s
serialPort.read()
def main():
ser_thread = MyThread_serial(name = "Thread-serial")
ser_thread.start()
gdb.execute("continue")
if __name__ == "__main__":
fptr = open("gdbOPs.txt", "a")
#connect to serial port
strPort = "/dev/ttyUSB0"
serialPort = Serial_Port(strPort, 9600)
#set signal interrupt to exit
signal.signal(signal.SIGINT, serialPort.close)
print('Press Ctrl+C to exit')
main()
Фон
У меня есть оборудование, которое отправляет строку в формате
[[12.12345678,12.12345678], [12.12345678,12.12345678], ...]
Но иногда в строке могут быть ошибки, подобные
[[12.12345678,12.12345678], [ 55,01 [12.12345678,12.12345678], ...]
Мне никогда не удавалось воспроизвести эту ошибку, и поэтому я решил написать скрипт, который ждет, пока ошибка не будет замечена, затем interrupts
GDB. Дамп стека и всех соответствующих переменных.
Пожалуйста, обратитесь к оригинальному вопросу C, чтобы узнать больше об ошибке
Вопрос
- Как мне создать динамическое прерывание? Т.е. при обнаружении сбойной строки я должен отправить
Ctrl+C
, чтобы остановить процесс и получить контроль над подсказкой.
- Как мой подход к поиску ошибки? Люди обычно используют такие методы тестирования? Не могли бы вы связать их?
Обновление
Ошибка была устранена путем замены функции sprintf
на функцию, которая не работает с 64 битами (в 32-битной среде ARM см. этот вопрос) напрямую. Пожалуйста, перейдите к исходному вопросу, чтобы найти новую используемую функцию.