Назад | Перейти на главную страницу

Процесс отправляет SIGINT при запуске с помощью Upstart

У меня есть приложение для Linux, которое открывает несколько последовательных устройств (/dev/ttyUSBX) и читает / записывает из них. Когда я запускаю его из командной строки (Ubuntu 10.04, bash), он работает отлично.

$sudo ./my_program /dev/ttyUSB0   #sudo for permissions on the device

Я хочу, чтобы эта программа запускалась при запуске и возрождалась, если она умирает, поэтому я помещаю ее в конфигурацию Upstart (/etc/init/*) и назвал это "my_service".

Когда я перезагружаю машину, выполняется my_service и запускается my_program. Однако через несколько секунд (примерно когда он открывает ttyUSB и читает с них) мой процесс получает SIGINT. Я не могу понять, откуда это. Это не проблема с разрешениями на устройствах, они отлично работают с open () и несколько байтов передаются нормально. С помощью waitsiginfo() Я смог получить si_code 0x80 или SI_KERNEL. Итак, я знаю, что это исходит не от другого процесса, а от самого ядра. Никто не ударил CTRL-C или ALT-CTL-DEL на консоли - почему ядро ​​отправляет мне SIGINT?

Хуже того, моя программа соответствующим образом завершает работу на основе этого сигнала - возрождается Upstart и сразу же снова получает SIGINT! Есть ли способ выяснить, откуда исходит этот сигнал и почему? Есть ли какой-то уровень отладки ядра, который мог бы пролить свет на это? Почему отличается поведение при запуске с помощью Upstart и вручную из bash?

Проблема решена, но это была ошибка программирования, не связанная с Upstart. Программа открывает устройство ttyUSB для необработанного (неканонического) ввода, но не сбрасывает флаг ISIG в termios. Всякий раз, когда был получен символ «CTRL-C» (0x02), ядро ​​генерировало SIGINT и отправляло его программе. Эта проблема возникла не из bash, потому что настройки termios сохраняются в файле, и что-то должно было открыть tty и очистить бит ISIG до выполнения моей программы. Этого не происходило при запуске прямо из Upstart. Я все еще хотел бы, чтобы был какой-то лучший способ регистрации / отладки сигналов, ptrace - это только половина ответа!

Программа отправляет SIGINT, когда она помещается в фоновый режим (подумайте ^ Z). Обычно вещи, которые собираются жить как демоны, улавливают сигнал и продолжают жить.

Убедитесь, что вы можете запустить программу из интерактивной оболочки, а затем перевести ее в фоновый режим с помощью ^ Z. Вполне возможно, что он тоже умрет.

Если это окажется ответом, у вас есть 2 возможности. Если это ваша программа, вы можете перехватить SIGINT. Если у вас нет доступа к источникам, или вы не хотите тратить дополнительное время на кодирование этой функции, или вы запускаете программу на некоторых версиях виртуальной машины Java, у которых есть проблемы с сигналами, тогда оберните свою программу в сценарий, который использует screen чтобы запустить и запустить вашу программу. Таким образом screen уходит в фоновый режим, но ваш код обманывается, думая, что он работает на переднем плане интерактивного сеанса.