【问题标题】:C program is interrupted during the execution of “system” functionC 程序在执行“系统”函数期间被中断
【发布时间】:2016-12-31 07:32:24
【问题描述】:

我的 C 代码有问题,基本上我需要通过 mutt 程序发送电子邮件。它必须在 GPIO 引脚出现中断时发送。下面列出了我的 sendMail 功能。我通过使用 system 函数实现了这一点。 Main 包含带有包含 sendMail 的 logAlarm 函数的循环。问题是当 system(cmd) 函数完成时,整个 C 程序停止。例如,当我将 sendMail 函数放在 main 的开头时,它可以工作并且正在向我的邮箱发送电子邮件而不停止整个程序,在循环中它设法发送它但它终止了程序。我尝试使用 & 符号在后台运行它,但没有帮助。

PS 我不知道这是否重要,但我也使用来自 setitimer 的系统调用以 2 秒的间隔检查一些事情,但我想这对这种情况没有影响。

有什么想法吗?

提前致谢:)

发送邮件功能:

void sendMail(char * msg, char * recipientMail){
 char cmd[100];
 char subject[30];
 char body[60];

 sprintf(body, "Intruder detected!!!\n%s", msg);
 strcpy(subject, "\"ALARM - SECURITY BREACH\"");
 sprintf(cmd,"echo \"%s\" | mutt -s %s %s &", body, subject, recipientMail);
 printf("%s\n\n", cmd);
 system(cmd);

}

这是我的主要功能的一部分:

while(1){

        sleep(1);

        if(prev_state == triggered && !emailDetach){
            if(!logAlarm()){
                printf("Error writing to log file!!!\n");
            }
            emailDetach = true;
        }
        //printf("Czas od poprzedniego alarmu: %d", millis() - alarmTriggeredTime);
        if((prev_state == triggered) && (millis() - alarmTriggeredTime >= ALARM_TIME)){

            digitalWrite(ALARM_ON_DIODE, LOW);
            digitalWrite(ALARM_OFF_DIODE, HIGH);
            //warunek czasowy osobno na syrene TODO
            if(!silentMode && (millis() - alarmTriggeredTime >= siren_alarm_time)){
                digitalWrite(SIREN, LOW);
            }
            prev_state = nottriggered;
        }

}

【问题讨论】:

  • 调试器会告诉你什么费用?它到底停在哪里?请参阅How to Ask 并提供minimal reproducible example
  • system() 是同步的,所以 sendmail() 在 cmd 完成之前不会返回。
  • 感谢@Olaf 建议使用调试器:D。它有很大帮助,这是 SIGSEGV 的错。 cmd 变量在一种情况下很小,它正在崩溃程序。谢谢!

标签: c email terminal terminate mutt


【解决方案1】:

好问题。根据描述,我认为 sendMail 功能可以正常工作。我没有和笨蛋一起工作过。但我使用过 system()。

系统所做的是,它派生出当前进程的子进程并使用 execve() 执行命令。所以问题应该出在系统的返回上。

所以,首先你应该检查系统函数的返回状态。如果您能够在 system() 下方制作 printf(),那么您对 ​​system() 没有任何问题。如果您无法在 system() 下方获取 printf,则 system() 正在杀死您的进程。 (通过发送 sigkill 或类似信号,但不发送 sigint 或 sigquit,因为它被 system() 忽略)。您正在 cmd 本身中创建一个子进程(将输出管道回显到 mutt)。可能这应该是根本原因。

如果你在这里发现问题,那么问题就很严重了,你会从“man system”的“NOTES”部分找到方向,因为你已经实现了那里提到的相同逻辑。首先尝试等待那里提到的条件。如果您仍然无法执行此操作,请尝试派生两个新的子进程,从该子进程运行 execl 或任何其他 exec 系列函数(“man 3 exec”)以运行 echo 和 mutt。

如果 system() 正常,则检查 logAlarm()。是否为 sendMail 提供了正确的参数?如果您收到“写入日志文件时出错!!!”,那么整个序列就可以了。

【讨论】:

  • 非常感谢您的 anwser,我正在做更多的研究,正如@Olaf 在评论中建议的那样,我使用 strace 命令进行调试,我注意到系统命令调用 SIGSEGV,它终止了我的程序,事情我猜为什么我的程序违反了内存?我需要更多地测试代码。我会尽快放日志
  • 好吧...错误出在 sendMail 函数中,cmd 变量太小而无法包含大字符串。它正在调用 SIGSEGV。我没有针对消息的固定长度对其进行测试,所以有时可以,因为 cmd var 小于 100 个字符,但在主程序中消息大于 100 个字符。真可惜:D。
猜你喜欢
  • 1970-01-01
  • 2012-06-06
  • 2023-03-08
  • 2022-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-16
相关资源
最近更新 更多