Если вы не можете прервать «непрерывное чтение» и это не связано с выключенным сервером NFS, вы обнаружили ошибку драйвера.
Время ожидания ввода-вывода в локальное фоновое хранилище не должно превышать 5 -10 минут. Поэтому, если вы набираете ^C
или ^Z
и ничего не происходит в течение 10 минут, это ошибка драйвера.
Предыстория заключается в том, что UNIX определяет, что так называемый fast IO
не может быть прерван сигналами, поскольку быстрый ввод-вывод завершится через обозримое время.
Прерывание операций ввода-вывода по сигналам приводит к большим накладным расходам, поскольку необходимо вернуться в чистое состояние. Все, что произошло после старта в ИО, нужно раскрутить и возврат может произойти только оттуда, откуда был инициирован ИО.
Хуже того, если драйвер фонового хранилища реализует прерываемый ввод-вывод, это вызовет неустранимые проблемы в файловых системах выше такого драйвера. Вы используете драйвер, предназначенный для использования в качестве фонового хранилища для файловой системы...
Вы можете позвонить dmesg
и проверить сообщения ядра о вашей проблеме. Если прерывание действительно не работает через 10 минут (, когда ожидается, что один системный вызов чтения или записи истечет по тайм-ауту, и есть шанс убить dd
между двумя такими системными вызовами ), вам необходимо перезагрузиться.
Если это устройство подключено к USB, вы можете попытаться извлечь устройство перед перезагрузкой.
Библиотека, содержащая функции printf
и exit
, является общей библиотекой (*.so
), которая динамически загружается после запуска программы. Адреса этих функций неизвестны до тех пор, пока динамический компоновщик не поместит библиотеку в адресное пространство процесса. Адреса могут меняться от одного запуска программы к другому.
Вы можете использовать отладчик gdb
, чтобы найти, где динамический компоновщик поместил функцию, запустив программу до точки останова, а затем введите p printf
в приглашении отладчика.
Чтобы избежать динамического связывания, вы можете статически связать библиотеки с вашей программой. Если вы сделаете это, адреса будут известны заранее и могут быть проверены с помощью readelf
. Чтобы скомпилировать программу статически, используя gcc
, добавьте параметр -static
в командную строку, например.:
gcc -static myprog.c -o myprog