简体   繁体   English

在Linux上测试SIGINT和SIGHUP时有趣的类似故障的行为

[英]Interesting glitch-like behavior when testing SIGINT and SIGHUP on linux

Lately have been testing out using signals such as SIGINT and SIGHUP and their role on ongoing processes on Linux. 最近一直在使用SIGINT和SIGHUP等信号及其在Linux上正在进行的进程中的作用进行测试。 Running the following code returned some interesting results. 运行以下代码返回一些有趣的结果。

 #include <signal.h> #include <stdio.h> void routine(int p){ puts("Not finishing"); sleep(2); } main(){ int i = 0; signal(SIGINT, routine); signal(SIGHUP, routine); while(1){ printf("%d \\n", i++); } } 

As you can see, it simply counts from 0 on an infinite loop. 如您所见,它只是在无限循环中从0开始计数。 Then, by using kill -SIGINT on the process it created, I got the following: 然后,通过在其创建的进程上使用kill -SIGINT,我得到了以下信息:

Routine 常规

As you can see, before the line I requested the routine to print, the program repeated the last number (and it does not happen always). 如您所见,在我要求打印例程的那一行之前,该程序重复了最后一个数字(而且并非总是如此)。 I would really like to know why. 我真的很想知道为什么。

It is likely that you are narrowly avoiding horrible bugs by accident. 您很可能会偶然地避免可怕的错误。

What I think is happening is that the signal sometimes interrupts while printf is in progress formatting the string into the output buffer. 我认为正在发生的事情是,有时在printf将字符串格式化为输出缓冲区时,信号有时会中断。 Then the puts in the signal handler inserts more string into the output buffer. 然后,信号处理程序中的puts将更多字符串插入输出缓冲区。 Then the handler returns, printf inserts the newline and flushes the buffer. 然后处理程序返回, printf插入换行符并刷新缓冲区。

But guess what would happen if this signal occurred just before the flush of a full 8K output buffer. 但是,如果该信号刚好在刷新整个8K输出缓冲区之前发生,将会发生什么情况。 The buffer positions would be at the end. 缓冲区位置将在末尾。 Then the puts call happens, not realizing that printf is already in process of flushing and clearing the buffer. 然后发生puts调用,但没有意识到printf已经在刷新和清除缓冲区中。 Where exactly would it be putting the puts string? 到底将把puts字符串放在哪里? At the beginning? 一开始? At the end? 在末尾? Would the excess data printf was in the process of writing write over the string that puts had added? 将多余的数据printf是在该字符串写入写的过程中puts了补充? All of those things are possible. 所有这些事情都是可能的。

Buffered C output is not reentrant and cannot be used in signal handlers. 缓冲的C输出不是可重入的,不能在信号处理程序中使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM