使用systemd运行C程序时的核心转储

时间:2018-05-14 09:31:08

标签: c daemon systemd

我在C中有一个程序在直接从命令行运行时运行良好但在使用systemd运行时失败:

Core was generated by `/usr/local/bin/midnite-modbusd'.
Program terminated with signal SIGFPE, Arithmetic exception.
#0  0x0000000000401308 in main (argc=1, argv=0x7ffeae390268) at src/midnite-modbusd.c:139
139                     slen= interval - (millis % interval);

有问题的代码:

//wait for start of each sample interval
gettimeofday(&tv,NULL);
millis= (long long unsigned)tv.tv_sec*1000 + (tv.tv_usec/1000);
slen= interval - (millis % interval);
i= (millis+slen) % 1000;
usleep (slen*1000);

完整代码is available on github

systyemd单位:

[Unit]
Description=Midnite Classic modbus data polling
After=network.target

[Service]
Type=simple
User=midnite-modbusd
ExecStart=/usr/local/bin/midnite-modbusd
Restart=on-failure

[Install]
WantedBy=multi-user.target

当程序与systemd一起运行时会有什么不同?

编辑1

似乎我的程序存在的主要问题只有在使用systemd运行时才会发生:

  • 它无法读取我的配置文件,该文件应该抛出错误消息并exit(1) because of invalid values
  • journactl并没有实时填写。使用journactl -f我必须等待几分钟才能看到突然出现的一堆日志

作为使用命令行进行测试的旁注,我运行:sudo -H -u midnite-modbusd /usr/local/bin/midnite-modbusd

2 个答案:

答案 0 :(得分:1)

配置文件中 sample_interval 的定义值将初始化 interval ,请检查文件是否正确并且 sample_interval 是否存在。 interval 的未初始化值可能会导致除以零的异常

答案 1 :(得分:0)

我在这段代码中发现了这个问题:

if (getppid()==1) {
    sprintf(str, "Daemon aready running");
    log_message(log_file_path,(char*)str);
    return;
}

此代码适用于程序打算将其自身作为旧样式运行的时间。守护进程。 我没有意识到,当systemd正在分叉它时,程序有一个父进程(因此getppid()在使用systemd而不是从命令行运行时返回1

无论如何它写得很糟糕:这个测试应该停止脚本。