Segmentation fault backtracked to vfprintf? - c

I get a segmentation fault and using gdb and backtrace, it is thrown at vprintf.
#0 0x006e8779 in vfprintf () from /lib/libc.so.6
#1 0x006f265f in fprintf () from /lib/libc.so.6
#2 0x08049fd1 in write_tofile (logfile=0x9843090 "~/www/log") at example.c:446
It happens when I call
file = fopen(log_file, "a"); // log_file = "~/www/log"
fprintf(file, buffer);
Can fopen handle files from different directories? Would anyone have a clue as to why it segfaults here?

Using '~' as an abbreviation for your home directory is a shell thing, and isn't necessarily available in C. This is likely to cause the fopen to fail, and you're not checking the return code.

You must never fail to check for errors in operations that aren't 100% under your control. If you don't know whether a file exists and the open operation must succeed (and that's something you really cannot know for sure, ever), you must test:
FILE * f = fopen(log_file, "a");
if (!f) { /*error, die? */ }
fprintf(f, buffer);
Also make sure that buffer is a valid pointer to the first character of a null-terminated array of characters, and that the string doesn't contain any format specifiers.
For just printing a raw string str, it is safer to use fputs(str, f), or fprintf(f, "%s", str) if you must.

Check the contents of buffer. You have either a unescaped % symbol and/or no null terminating character.

Presumably fopen failed & returned a NULL pointer.
You should check the return value of fopen before using it, and use errno to determine what the error was.

Related

Segmentation Fault when reading from file - fgets()

Trying to read from a file to use in a small game I've created. I'm using the fgets function. It's returning a Segmentation Fault, not sure why.
The file it's reading, just contains "20 10" in a txt file as this is the map size.
My readfile function is shown below
if (argc == 2) {
f = fopen("map.txt", "r");
if (NULL == f) {
printf("File cannot be opened.");
}
while (fgets(fileRead, 50, f) != NULL) {
printf("%s", fileRead);
}
fclose(f);
}
The if (argc == 2) can be ignored, this is just to make this section run, as I'm modifying a file so just running this function by satisfying that if statement.
I am fairly new to C, so apologies if I'm missing something minor. Worth noting I'm programming in C89 and using the -Wall -ansi -pedantic compile options, as this is University work and the tutors want us to do C89.
EDIT:
char userInput, fileRead[50];
FILE* f;
Declaration of variables.
Assuming that your problem is indeed in your posted code and not somewhere else in the program, then I believe that your problem is caused by the following issue:
After calling fopen, you check the return value of the function immediately afterwards, to verify that it succeeded. However, if it doesn't succeed and it returns NULL, all you do is print an error message to stdout but continue execution as if it succeeded. This will cause fgets to be called with NULL as the stream argument, which will invoke undefined behavior and probably cause your segmentation fault.
In the comments section, you raised the following objection to this explanation:
However it doesn't print the error message anyway and still segmentation faults, so I think the problem isn't here?
This objection of yours is flawed, for the following reason:
When a segmentation fault occurs, execution of the program is immediately halted. The content of the output buffer is not flushed. This means that output can get lost when a segmentation fault happens. This is probably what is happening in your case.
If you want to ensure that the output actually gets printed even in the case of a segmentation fault, you should flush the output buffer by calling fflush( stdout ); immediately after the print statement. Alternatively, you can print to stderr instead of stdout. In constrast to stdout, the stream stderr is unbuffered by default, so that it does not have this problem.
You can test whether my suspicion is correct by changing the line
printf("File cannot be opened.");
to
printf("File cannot be opened.");
fflush( stdout );
or to:
fprintf( stderr, "File cannot be opened." );
If the error message now gets printed, then this probably means that my suspicion was correct.
In any case, I recommend that you change the lines
if (NULL == f) {
printf("File cannot be opened.");
}
to the following:
if (NULL == f) {
fprintf( stderr, "File cannot be opened." );
exit( EXIT_FAILURE );
}
That way, the program will exit immediately if an occur occurs, instead of continuing execution.
Please note that the code posted above requires you to #include <stdlib.h>.

why the program give "Segmentation fault" after 1018 try

I'm writing a C code to open txt file and read two lines on it then print the value
it worked for 1018 time then it gives "Segmentation fault"
I've tried to flush the buffer but it don't work
while(running) {
i = 0;
if ((fptr = fopen("pwm.txt", "r")) == NULL) {
printf("Error! File cannot be opened.");
// Program exits if the file pointer returns NULL.
exit(1);
}
fptr = fopen("pwm.txt","r");
while (fgets(line,sizeof(line), fptr)){
ppp[i]=atoi(line);
i++;
}
fclose(fptr);
printf("%d %d\n",ppp[0],ppp[1]);
rc_servo_send_pulse_us(ch, 2000);
rc_usleep(1000000/frequency_hz);
}
Actually, the file-opening is the likely culprit: On e.g. Linux there's a limit to how many files you can have open, and it typically defaults to 1024. A few files are used for other things, and your program probably uses some other file-handles elsewhere, leaving only around 1018 left over.
So when you open the file twice, you leak the file handle from the first fopen call, and then your second fopen call will fail and give you a NULL pointer in return. And since you don't check for NULL the second time you attempt to use this NULL pointer and have a crash.
Simple solution: Remove the second and unchecked call to fopen.

fclose() always returns EOF

I have a function that reads integers with certain format from a file.
It works fine as desired, but whenever I tried to close the file with fclose(),
fclose() always returns EOF.
Any suggestions why? I am a student and still learning.
I have put the code below. Please let me know if you need the "processing" code. Thanks :)
// Open the file
FILE *myFile = fopen(fileName, "r");
if(myFile == NULL){
//Handle error
fprintf(stderr, "Error opening file for read \n");
exit(1);
}
while(myFile != EOF)
{
// read and process the file
// this part works.
}
// always returns EOF here. WHY?
if (fclose(myFile) == EOF) {
// Handle the error!
fprintf(stderr, "Error closing input file.\n");
exit(1);
}
printf("Done reading the file.");
EDIT:
Thank you for all the replies. Sorry I cannot post the code as this is part of my homework. I was trying to get some help, I am not asking you guys to make the code for me. Posting code is illegal according to my Prof (since other students can see and probably copy, that's what he told me). I can only post the code after Sunday. For now, I will try to modify my code and avoid using fscanf. Thanks and my apology.
This:
while(myFile != EOF)
is actually illegal (a constraint violation). Any conforming C compiler is required to issue a diagnostic; gcc, by default, merely issues a warning (which does qualify as a "diagnostic").
If gcc gave you a warning, you should pay attention to it; gcc often issues warnings for things that IMHO should be treated as fatal errors. And if it didn't give you a warning, you're probably invoking it with options that disable warnings (which is odd, because it does produce that warning by default). A good set of options to use is -Wall -Wextra -std=c99 -pedantic (or adjust the -std=... option to enforce a different version of the standard if you like).
myFile is of pointer type, specifically FILE*. EOF is of type int, and typically expands to (-1). You cannot legally compare a pointer value to an integer value (except for the special case of a null pointer constant, but that doesn't apply here.)
Assuming the program isn't rejected, I'd expect that to result in an infinite loop, since myFile would almost certainly never be equal to EOF.
You could change it to
while (!feof(myFile))
but that can cause other problems. The correct way to detect end-of-file while reading from a file is to use the value returned by whatever function you're using read the data. Consult the documentation for the function you're using to see what it returns when it encounters end-of-file or an error condition. The feof() function is useful for determining, after you've finished reading, whether you encountered end-of-file or an error condition.
Since there is nothing that you can do to a regular file open in read-only-mode that would cause a fclose to error out, you very probably have a bug in the code you didn't show which is stomping on the myFile structure.
Also the test myFile != EOF will never be true because you set it to the return of fopen which will never give you EOF and you already checked it for NULL Did you mean something like:
while((c = fgetc(myFile)) != EOF) {
// do stuff
}
What the errno said? add this to your code:
#include <errno.h>
#include <string.h>
if (fclose(myFile) == EOF) {
// Handle the error!
fprintf(stderr, "Error closing input file. and errno = %d, and error = %s\n", errno, strerror(errno));
exit(1);
}
Hope this help.
Regards.
while(myFile != EOF)
{
// read and process the file
// this part works.
}
If this part is ok then
fclose(myFile);
definitely return you EOF.Because the while loop terminates only myFile == EOF(this is a wrong comparison, do not ignore warnings).comparision between pointer and int.As EOF is a macro defined in stdio.h file And according to glibc it -1.Your loop terminates that means your myFile pointer changed to EOF some whire.This is your mistake.
just go through your code you must be change the FILE pointer myFile which should not be over written by you As it point to a file structure
which is used for all file operation.
NOTE
myFile which is a pointer to a file should not be used as lvalue in any assignment statement.
Change while(myFile != EOF){...} by while(!feof(myFile)){...}
myFile is a pointer to a FILE struct (a memory address). Not a "end of file" indicator.

C segmentation faults due to fopen(). How to trace and what to look for?

(this was asked on ffmpeg-devel list, but counted way offtopic, so posting it here).
ffmpeg.c loads multiple .c's, that are using log.c's av_log -> av_log_default_callback function, that uses fputs;
void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl)
{
...
snprintf(line, sizeof(line), "[%s # %p] ", (*parent)->item_name(parent), parent);
... call to colored_fputs
Screen output:
static void colored_fputs(int level, const char *str){
...
fputs(str, stderr);
// this causes sigsegv just by fopen()
FILE * xFile;
xFile = fopen('yarr', 'w');
//fputs(str, xFile);fclose(xFile); // compile me. BOOM!
av_free(xFile); // last idea that came, using local free() version to avoid re-creatio
Each time, when fopen is put into code, it gives a segmentation fault of unknown reason. Why this kind of thing may happen here? Maybe due to blocking main I/O?
What are general 'blockers' that should be investigated in such a situation? Pthreads (involved in code somewhere)?
fopen takes strings as arguments, you're giving it char literals
xFile = fopen('yarr', 'w');
Should be
xFile = fopen("yarr", "w");
if(xFile == NULL) {
perror("fopen failed");
return;
}
The compiler should have warned about this, so make sure you've turned warning flags on (remeber to read them and fix them)

segfault during fclose()

fclose() is causing a segfault. I have :
char buffer[L_tmpnam];
char *pipeName = tmpnam(buffer);
FILE *pipeFD = fopen(pipeName, "w"); // open for writing
...
...
...
fclose(pipeFD);
I don't do any file related stuff in the ... yet so that doesn't affect it. However, my MAIN process communicates with another process through shared memory where pipeName is stored; the other process fopen's this pipe for reading to communicated with MAIN.
Any ideas why this is causing a segfault?
Thanks,
Hristo
Pass pipeFD to fclose. fclose closes the file by file handle FILE* not filename char*. With C (unlike C++) you can do implicit type conversions of pointer types (in this case char* to FILE*), so that's where the bug comes from.
Check if pepeFD is non NULL before calling fclose.
Edit: You confirmed that the error was due to fopen failing, you need to check the error like so:
pipeFD = fopen(pipeName, "w");
if (pipeFD == NULL)
{
perror ("The following error occurred");
}
else
{
fclose (pipeFD);
}
Example output:
The following error occurred: No such file or directory
A crash in fclose implies the FILE * passed to it has been corrupted somehow. This can happen if the pointer itself is corrupted (check in your debugger to make sure it has the same value at the fclose as was returned by the fopen), or if the FILE data structure gets corrupted by some random pointer write or buffer overflow somewhere.
You could try using valgrind or some other memory corruption checker to see if it can tell you anything. Or use a data breakpoint in your debugger on the address of the pipeFD variable. Using a data breakpoint on the FILE itself is tricky as its multiple words, and is modified by normal file i/o operations.
You should close pipeFD instead of pipeName.

Resources