I have a piece of C code where I try to write a buffer into an opened output file.I am getting a segmentation fault when I try to run the code.
if (fwrite(header, record_size, 1, uOutfile) != 1)
{
return 0;
}
The header is a properly populated and I am able to print out the contents of the header.the size of the buffer header is definitely greater than the record_size.Is there anything else worth checking.?Any other reason where fwrite can cause a segfault.Gdbing the problem gave the following output
0x00007ffff6b7d66d in _IO_fwrite (buf=0x726d60, size=16, count=1, fp=0x738820) at iofwrite.c:43
43 iofwrite.c: No such file or directory.
in iofwrite.c
it seems to suggest that the output file has not been created.how ever and ls -l on my directory shows the output file of size 0 bytes.
I would greatly appreciate if someone could throw some light on the problem.
EDIT: Code that opens the file:
outfd = open(out, O_RDWR|O_CREAT|O_TRUNC|O_LARGEFILE, 0664);
if (outfd == -1) {
dagutil_panic("Could not open %s for writing.\n", out);
}
uOutfile = fdopen(outfd, "w");
I don't think there's enough here to know for sure what your problems are, but here are some thoughts:
Show us the code involving your FILE * (uOutFile) and your buffer (header) — we can then see if you're borking memory somewhere between.
Run your code through valgrind: You're getting a segfault, so it could probably catch what you're doing wrong.
In gdb, examine the contents of both header and uOutFile (not just the pointer, but the pointed-to-memory.) (You'll have to use some smarts to figure out if uOutFile looks right, but you should be able to up-or-down determine if header is correct.)
To add to this: my general debug strategy when I get segfaults is:
gdb's backtrace. Tells me where the segfault happened. Usually, this is enough to uncover the dumb thing I did.
Look at the pointers in the vincinity of the crash. Is the pointer correct, and is the pointed-to data correct? (esp. if you see something strange like 0xdeadbeef)
Valgrind Valgrind Valgrind
(2 & 3 are in no particular order.)
Related
I wrote the following code in GDB online debugger :
#include <stdio.h>
int main()
{
printf("jkjkkjkj");
int p , n;
FILE *fp;
printf("jkjkkjkj2");
fp = fopen("abc.txt","r");
while ( (n = getc(fp))!= EOF)
{
printf( "the chareacter here is %d \n", n);
}
n = fclose(fp);
return 0;
}
While executing the code I am getting a segmentation fault at the line where I am trying to fetch the characters from the file. I know that as the file does not exist the segmentation fault error is coming.
However, what intrigues me is the absence of the messages that I am trying to print on the screen. I tried checking on debugger and once I found:
optimized out written near the line no
However, I tried putting getchar() here and there, the messages got printed on the screen even if the segmentation fault persists.
How to explain this? Why is this happening? Why are the messages printed when I am putting getchar() at different places?
I had tried writing this code on a Solaris server and compiling using GCC. The code got compiled but I did not get any output message even when a file with the name provided in the directory existed.
As answered by Yunnosch, you probably forgot to check against failure of fopen(3). A better habit is to always check that, at least by coding:
fp = fopen("abc.txt","r");
if (fp == NULL) { perror("fopen abc.txt"); exit(EXIT_FAILURE); };
and take the habit of doing at least that everywhere. Using perror(3) (or strerror(3) with errno(3)) is a useful habit to get, since you want some reason related to the failure (given by errno perhaps thru perror).
More generally, always read the documentation of functions that you are using (for standard functions, at least on some reference website, and possibly in the C11 standard n1570), and take care of handling their failure (at the very least, by checking against failure and exiting with a useful message to stderr); for Unix functions, see their man pages (on Linux, start on intro(2) and intro(3); for Solaris, start with intro(2) & intro(3)..). In your Unix terminal, try also man fopen ... For POSIX standard, start here.
what intrigues me is the absence of the messages that I am trying to print on the screen.
That is simple. stdout is buffered (see also setvbuf(3)), and often line-buffered. So a printf which does not end with a \n has its output still inside the buffer, and not yet on the screen. The habit to get is to almost always end your printf(3) control format string with a newline, or else to flush the buffer explicitly using fflush(3).
For a newbie, there are few reasons to avoid ending your printf with an explicit \n. So use instead
printf("jkjkkjkj\n");
Otherwise, call fflush(NULL); quite often in your program. BTW, for these buffering reasons, fflush(NULL) should be done before calls to system(3), fork(2), execve(2) and other important program-wide functions.
optimized out written near the line no
That probably happens in the C standard library itself (e.g. in getc from some libc.so), which is usually not compiled with debug information. In practice, trust your C standard library: you are much more likely to have bugs in your code that in libc.
Your own source code should be compiled with gcc -Wall -Wextra -g (asking the GCC compiler to give all warnings and debug info in DWARF format, usable by the gdb debugger) and you need to improve your code to get no warnings at all before using the gdb debugger.
Be aware of undefined behavior, spend several hours reading about UB, and be scared of UB.
Try guarding against NULL in fp and for good measure make sure the debug output gets printed (as in comment by Some Programmer Dude).
#include <stdio.h>
int main(void)
{
int p , n;
FILE *fp;
printf("jkjkkjkj2\n");
fp = fopen("abc.txt","r");
if (NULL != fp)
{
while ( (n = getc(fp))!= EOF)
{
printf( "the chareacter here is %d \n", n);
}
n = fclose(fp);
} else
{
printf("File opening failed somehow!\n");
}
return 0;
}
Note the nice touch (by Basile Starynkevitch) to only close what was successfully opened.
When I run the program it prints out "SUCCESS!!!!" if it works alright, but I keep getting seg faults and I can't seem to figure out where. Can someone help me determine what exactly causes the signal SIGABRT and what is the most likely cause of why getting segmentation faults?
My code is written in c.
EDIT:
In my main code on line 97 I have the function fclose(fp) but I should have already read through it in another function. Here is my code from main.c:
FILE *fp = NULL;
if(fp = fopen(full_filename, "r")){
Node* tree = NULL;
tree = parser(fp);
printTree(tree, 1);
fclose(fp);
}
else
printf("Error file DNE\n");
return 0;
The function parser gets the file pointer and sends that file pointer to another function called scanner. Then scanner creates a list of words from that file. Then parser checks grammar of the words.
EDIT 2:
I got rid of fclose(fp) in main and when I ran it in gdb, I got no errors. But when I ran it without gdb I still get a seg fault.
There isn't too much information, but looking at the trace it would be my guess that you are trying to close a file with fclose() or iofclose(), and the file may not exist, or it is not open.
Conclusion
The problem must lie in your parser() function. It seems it is altering your file pointer and making it invalid.
Explanation
I state this because I it can't enter your if(fp = fopen(full_filename, "r")) statement unless the pointer is valid, but when you try to close it, the pointer seems to be invalid.
Note that
The only line which is able to affect your pointer is the one showing the folowing:
tree = parser(fp);
So I believe this is just a problem on unix and that it occurs at the first fscanf if the Clion debugger was right, but I don't know why I get the error- Process finished with exit code 139 (interrupted by signal 11: SIGSEGV) - why?
struct loginInformation
{
char username[USERNAME_LENGTH];
char password[PASSWORD_LENGTH];
int type;
}accounts[NUM_OF_ACCOUNTS];
void createAccountsFromFile()
{
FILE *input = fopen("accounts.txt", "r");
int counter;
for(counter = 0; counter < NUM_OF_ACCOUNTS; counter++)
{
fscanf(input, "%s", accounts[counter].username);
fscanf(input, "%s", accounts[counter].password);
fscanf(input, "%d", &accounts[counter].type);
}
}
int main()
{
createAccountsFromFile();
}
accounts.txt
user1
pass1
0
user2
pass2
1
user3
pass3
2
user4
pass4
3
It means the program crashed before it exited. You need to debug the program. For example, you need to check whether the file is successfully opened after fopen.
SIGSEGV are not always thrown due to a root cause of memory access problems...
Perl throws a 139 on Unix usually because of file I/O. You might have accidentally deleted your input files.
TL;DR: Your program tried to access a memory location it had no permissions to access, so the operating system killed it.
First: The code "139" doesn't matter, forget about the number. Your program was terminated after "getting a SIGSEGV", or a signall regarding a segmentation violation. Read about what that means here:
What causes a SIGSEGV
(never mind that question is about C++, same idea.)
Now, why would this happen? You must be making some assumptions you shouldn't be. Looking at your code, it might be:
Reading a very long string from the file which exceeds the bounds of the loginInformation array - and perhaps even the bounds of the memory region allocated to your program overall.
Scanning from an invalid-state/uninitialized/null file descriptor, as in #xuhdev's answer
(Unlikely/impossible) Ignoring some error generated by one of the fscanf() calls (you need to check errno if a scan failed).
I think that covers it although maybe I missed something. Instead of speculating you can actually check what happened using a debugger on the core dump:
How do I analyze a program's core dump file with GDB when it has command-line parameters?
On Perl programmation RC 139 caused by "Out of memory" for me.
Because there have been too much data in a variable (millions).
I have done a segmentation manualy by release (undef) this variable regularly.
This solved this.
I'm writing a buffer into a binary file. Code is as in the following :
FILE *outwav = fopen(outwav_path, "wb");
if(!outwav)
{
fprintf(stderr, "Can't open file %s for writing.\n", outwav_path);
exit(1);
}
[...]
//Create sample buffer
short *samples = malloc((loopcount*(blockamount-looppos)+looppos) << 5);
if(!samples)
{
fprintf(stderr, "Error : Can't allocate memory.\n");
exit(1);
}
[...]
fwrite(samples, 2, 16*k, outwav); //write samplebuffer to file
fflush(outwav);
fclose(outwav);
free(samples);
The last free() call causes me random segfaults.
After several headaches I thought it was probably because the fwrite call would execute only after a delay, and then it would read freed memory. So I added the fflush call, yet, the problem STILL occurs.
The only way to get rid of it is to not free the memory and let the OS do it for me. This is supposed to be bad practice though, so I'd rather ask if there is no better solution.
Before anyone asks, yes I check that the file is opened correctly, and yes I test that the memory is allocated properly, and no, I don't touch the returned pointers in any way.
Once fwrite returns you are free to do whatever you want with the buffer. You can remove the fflush call.
It sounds like a buffer overflow error in a totally unrelated part of the program is writing over the book-keeping information that free needs to do its work. Run your program under a tool like valgrind to find out if this is the problem and to find the part of the program that has a buffer overflow.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
On running the following script, I get segmentation fault. The output consists of "here 5a". But nothing beyond it. Any suggestions on what might be going wrong?
if(model==1)
fptr3=fopen("poisson.pro","r");
if(model==2)
fptr3=fopen("jtt.pro","r");
if(model==3)
fptr3=fopen("estimate.pro","r");
printf ("here 5a\n");
for (i=0;i<20;i++)
fscanf(fptr3,"%lf", &freq[i]);
printf ("here 5ai\n");
for (i=0;i<20;i++)
{
printf ("here 5b\n");
for (j=0;j<20;j++)
{
printf ("here 5c\n");
fscanf(fptr3,"%lf", &prob[i][j]);
if(model==3)
prob[i][j]=prob[i][j]/10000.0;
}
}
UPDATE
double freq[20], prob[20][20];
Are you sure this code is called and "model" is either 1, 2, or 3? If not, fptr3 would not be set, so if you try to do anything with it you'd be in trouble.
Try this instead?:
void modeltest (int model)
{
FILE *fptr3 = NULL;
int i = 0;
int j = 0;
double freq[20], prob[20][20];
if(model==1) fptr3=fopen("poisson.pro","r");
if(model==2) fptr3=fopen("jtt.pro","r");
if(model==3) fptr3=fopen("estimate.pro","r");
printf ("here 5a\n");
if (fptr3 != NULL) {
for (i=0;i<20;i++) fscanf(fptr3,"%lf", &freq[i]);
printf ("here 5ai\n");
for (i=0;i<20;i++) {
printf ("here 5b\n");
for (j=0;j<20;j++) {
printf ("here 5c\n");
fscanf(fptr3,"%lf", &prob[i][j]);
if(model==3) prob[i][j]=prob[i][j]/10000.0;
}
}
}
else {
printf ("fptr3 is NULL!\n");
}
}
An additonal note. Please, please, please consider consistent brace styles! :)
Is this C# ???? wooow no kidding you are getting segfaults...
Do you know what return codes are for ???
You really need to improve your code before asking for this kind of help....this is really unreadable, and ugly code...
Start adding some check to your file pointers
if(1==model)
{
fptr3=fopen("poisson.pro","r");
if(null == fptr3)
{
perror("Fopen failed");
}
...
valgrind is the sovereign remedy for segfaults in C. It finds errors before the segfault and tells you exactly what you did wrong. For maximum benefit, compile with debugging symbols turned on.
I agree with Daniel, you need to be checking your return values and pointers.
I also agree that you need to do a better job blocking and formatting your code. Supposing that you are the only one that ever reads it, in a couple of weeks even you will have forgotten enough that you won't be able to follow it.
Towards Matthews point, you could try deleting everything starting with the line:
printf ("here 5ai\n");
Of course, only bother with this after checking the file pointer.
Another crazy idea would be stepping through it with a debugger. I know it's hard to use a debugger when you have such great debugging options as the printf statement, but sometimes a debugger can be a huge time saver (for example, when you keep getting segfault). Also, learning how to use the debugger for the platform you are developing on is one of the things that separates good coders from the pack of average hacks. (FYI, you could even try looking at your core in the debugger and maybe see exactly where the problem is. (Hint: if you don't have a core file try 'man ulimit'.))
If you are going to insist on using printf as your only means of debug, then call flush right after each use.
What's freq defined as? What's prob defined as?
Is the first for loop meant to only run fscanf for freq? Or is it supposed to encompass the entire block?
EDIT: Rationale - If all you see is 5a, then it's faulting in the fscanf on freq. You may have allocated too little space for freq, or used an incorrect type.
Check the return code and print if needed the error code of your files with perror() (see. daniel answer). Calling fscanf() with a FILE * to NULL, will surely do a segfault.
As you specified %lf, freq must be an array of at least 20 doubles, not just float.
See man ffrintf().
use a debugger instead of printf().
You should post the contents of the beginning of whatever file is getting opened since it's crashing in fscanf. Either the file doesn't exist, or it's malformed when stacked against to how you are trying to parse it.