Objective: Write This line must be printed
into log file mib_log_test
in case of program hangs/stuck because of some weird reason.
For simplicity, wrote a C program as below:
#include <stdio.h>
#include <stdlib.h>
#define FILE_NAME "./mib_log_test"
FILE *fp = NULL;
int main()
{
fp = fopen(FILE_NAME, "w+");
if (fp == NULL) {
fprintf(stderr, "Unable to open %s file", FILE_NAME);
exit(EXIT_FAILURE);
}
fprintf(fp, "This line must be printed\n");
while(1);
return 0;
}
Upon compiling and running above program, it will never be terminated itself because of infinite loop. So I have to press ctrl + c
to terminate it. with ctrl + c
I do not see This line must be printed
gets written in my logfile(mib_log_test
)
And If I override default SIGINT handler as shown below, This line must be printed
gets written in my logfile(mib_log_test
).
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#define FILE_NAME "./mib_log_test"
FILE *fp = NULL;
void sigint_handler(int sig_num)
{
exit(EXIT_FAILURE);
}
int main()
{
fp = fopen(FILE_NAME, "w+");
if (fp == NULL) {
fprintf(stderr, "Unable to open %s file", FILE_NAME);
exit(EXIT_FAILURE);
}
signal(SIGINT, sigint_handler);
fprintf(fp, "This line must be printed\n");
while(1);
return 0;
}
Question : What default SIGINT handler does that leads to not writing log messages in above case?
Stdio file buffers are block-buffered by default and when it crashes it doesn't flush the file buffer so that the buffered output gets lost.
One solution is to call
fflush(fp)
after eachfprintf(fp, ...)
but that is rather tedious.Another solution is to use
setvbuf
to set the file to line-buffered mode immediately after opening the file, so that it flushes the buffer for you on each new-line symbol:This also makes
tail -f <logfile>
output immediate and line by line rather than delayed and in blocks.