我有一个Linux应用程序,它打开了几个串行设备( /dev/ttyUSB X),并从它们读取/写入。 当我从命令提示符(Ubuntu 10.04,bash)运行它,它完美的作品。
$sudo ./my_program /dev/ttyUSB0 #sudo for permissions on the device
我希望这个程序能够在启动时运行,如果它死了就重新生成 – 所以我把它放到Upstart config( /etc/init/* )中,并把它叫做“ my_service ”。
当我重新启动机器时,my_service执行并运行my_program。 然而,几秒钟后(当它打开ttyUSB并从中读取时),我的进程收到一个SIGINT。 我无法确定它来自哪里。 这不是在设备上的权限问题,他们打开()罚款和几个字节得到转移确定。 使用waitsiginfo()我能够得到0x80或SI_KERNEL 。 所以我知道这不是来自另一个进程,而是来自内核本身。 没有人在控制台上击CTRL – C或ALT – CTL – DEL – 为什么内核给我一个SIGINT ?
更糟糕的是,根据这个信号,我的程序正常退出 – 被Upstart重新生成,并且再次SIGINT'ed! 有什么办法可以找出这个信号源自哪里,为什么? 是否有一定程度的内核debugging,可以启用一些这样的灯光? 为什么Upstart和bash手动启动的不同行为?
问题解决了,虽然这是一个编程错误,并没有涉及到Upstart。 该程序打开ttyUSB设备的原始(非规范)input,但它没有清除termios中的ISIG标志。 只要收到“CTRL-C”字符(0x02),内核就会生成SIGINT并将其发送到程序。 这个问题并没有从bash中发生,因为termios设置在文件上是持久的,而且在我的程序执行之前必须打开tty并清除ISIG位。 从Upstart直接运行时,不会发生这种情况。 我仍然希望有更好的方法来logging/debugging信号,ptrace只是答案的一半!
当一个程序放到后台时发送一个SIGINT信号(想想^ Z)。 通常情况下,作为守护进程的东西会陷入信号并继续生存下去。
validation,如果你可以从交互式shell启动程序,然后通过^ Z把它放到后台。 它也有可能死亡。
如果这被certificate是答案,你有两种可能性。 如果是你的程序,你可以捕获SIGINT。 如果您无法访问源代码,或者不想花费额外的时间来编写此function,或者您在某些版本的Java VM上运行程序时遇到了信号问题,那么将程序包装在使用screen的脚本中开始并运行你的程序。 通过这种方式, screen进入后台,但是你的代码被愚弄,认为它在交互式会话的前台运行。