调试难以重新创建C bug。动态断点

时间:2018-09-06 15:36:22

标签: c gdb embedded gdb-python

我很难重新创建错误,并且希望在发现错误后使用python GDB script来停止该过程(我将在调试中运行它,直到重新生成错误为止)。关于Stray chars seen out of 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环境中,请参考this问题)直接解决了该错误。请转到原始问题以查找所使用的新功能。

0 个答案:

没有答案