Отладка для трудно воссоздать ошибку C.Динамическая точка останова - PullRequest
0 голосов
/ 06 сентября 2018

Мне трудно восстановить ошибку, и я надеюсь использовать 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, чтобы узнать больше об ошибке

Вопрос

  1. Как мне создать динамическое прерывание? Т.е. при обнаружении сбойной строки я должен отправить Ctrl+C, чтобы остановить процесс и получить контроль над подсказкой.
  2. Как мой подход к поиску ошибки? Люди обычно используют такие методы тестирования? Не могли бы вы связать их?

Обновление

Ошибка была устранена путем замены функции sprintf на функцию, которая не работает с 64 битами (в 32-битной среде ARM см. этот вопрос) напрямую. Пожалуйста, перейдите к исходному вопросу, чтобы найти новую используемую функцию.

...