Почему мой долго работающий скрипт Python аварийно завершает работу с «неверным указателем» после запуска в течение примерно 3 дней? - PullRequest
3 голосов
/ 08 апреля 2019

Я написал скрипт на python 3, который проверяет SPI-ссылку на FPGA.Он работает на Raspberry Pi 3. Тест работает следующим образом: после перевода FPGA в тестовый режим (нажимной переключатель) отправьте первый байт, который может иметь любое значение.Затем дальнейшие байты отправляются на неопределенный срок.Каждый из них увеличивается на первое отправленное значение, усеченное до 8 бит.Таким образом, если первое значение равно 37, FPGA ожидает следующую последовательность:

37, 74, 111, 148, 185, 222, 4, 41 ...

Некоторые дополнительные выводы ввода / выводаиспользуются для сигнализации между устройствами - RUN (выход RPi) начинает тестирование (необходимо, потому что время ожидания FPGA составляет около 15 мсек, если ожидается байт), а ERR (выход FPGA) выдает ошибку.Таким образом, ошибки могут быть подсчитаны на обоих концах.

Кроме того, скрипт RPi записывает в одну строку сводку отправленных байтов и количество ошибок в миллионах байтов.

Все это прекрасно работает.Но после запуска в течение примерно 3 дней я получаю следующую ошибку на RPi:

free (): неверный указатель: 0x00405340

Я получаю точно такую ​​же ошибку на двух идентичных тестовых настройках, дажетот же адрес памяти.В последнем отчете говорится, что «отправлено 4294M байт, 0 ошибок»

Кажется, я доказал связь с SPI, но я обеспокоен тем, что эта долго работающая программа не работает без видимой причины.

Здесьважная часть моего тестового кода:

def _report(self, msg):
        now = datetime.datetime.now()
        os.system("echo \"{} : {}\" > spitest_last.log".format(now, msg))

    def spi_test(self):
        global end_loop
        input("Put the FPGA board into SPI test mode (SW1) and press any key")
        self._set_run(True)
        self.END_LOOP = False
        print("SPI test is running, CTRL-C to end.")
        # first byte is sent without LOAD, this is the seed
        self._send_byte(self._val)
        self._next_val()
        end_loop = False
        err_flag = False
        err_cnt = 0
        byte_count = 1
        while not end_loop:
            mb = byte_count % 1000000 
            if mb == 0:
                msg = "{}M bytes sent, {} errors".format(int(byte_count/1000000), err_cnt)
                print("\r" + msg, end="")
                self._report(msg)
                err_flag = True
            else:
                err_flag = False
            #print("sending: {}".format(self._val))
            self._set_load(True)
            if self._errors and err_flag:
                self._send_byte(self._val + 1)
            else:
                self._send_byte(self._val)
            if self.is_error():
                err_cnt += 1
                msg = "{}M bytes sent, {} errors".format(int(byte_count/1000000), err_cnt)
                print("\r{}".format(msg), end="")
                self._report(msg)
            self._set_load(False)
            # increase the value by the seed and truncate to 8 bits
            self._next_val()
            byte_count += 1

        # test is done
        input("\nSPI test ended ({} bytes sent, {} errors). Press ENTER to end.".format(byte_count, err_cnt))
        self._set_run(False)

(Примечание для пояснения: есть опция командной строки для искусственного создания ошибки через каждый миллион байтов. Отсюда и переменная "err_flag".)

Я пытался использовать python3 в консольном режиме, и, похоже, нет проблем с размером переменной byte_count (не должно быть, согласно тому, что я читал об ограничениях целочисленного размера python).

Кто-нибудь имеет представление о том, что может вызвать это?

...