Unanticipated Segmentation Fault in C

Unexpected Segmentation Fault while using functions

The value of the variable "game" which the function game_print_data() received in function game_loop_init() is NULL. Because the function game_create_from_file() did not update the value of "game" in game_loop_init().

C - Unexpected Segmentation Fault on strtok(...)

you are first checking if token is not equal to NULL(when it is, it breaks out of the while loop). Then you are comparing token, which is a NULL with a constant NUMBER? here: strcmp(token, 0) when strcmp expects 2 strings, you provide a number. strcmp will try to fetch a string at 0th address(or NULL) giving you a segmentation fault.

while(strcmp(token, 0) != 0){
token = strtok(NULL, ch);
printf("%s\n",token);
}

Also this piece of code should be something like the following:

change

  char * token = strtok(from, ch);
printf("%s\n",token);
while(token != NULL){
token = strtok(NULL, ch);
printf("%s\n", token);
}

to

  char * token = strtok(from, ch);
printf("%s\n",token);
while(token != NULL){
printf("%s\n", token);
token = strtok(NULL, ch);
}

Why is a segmentation fault not recoverable?

When exactly does segmentation fault happen (=when is SIGSEGV sent)?

When you attempt to access memory you don’t have access to, such as accessing an array out of bounds or dereferencing an invalid pointer. The signal SIGSEGV is standardized but different OS might implement it differently. "Segmentation fault" is mainly a term used in *nix systems, Windows calls it "access violation".

Why is the process in undefined behavior state after that point?

Because one or several of the variables in the program didn’t behave as expected. Let’s say you have some array that is supposed to store a number of values, but you didn’t allocate enough room for all them. So only those you allocated room for get written correctly, and the rest written out of bounds of the array can hold any values. How exactly is the OS to know how critical those out of bounds values are for your application to function? It knows nothing of their purpose.

Furthermore, writing outside allowed memory can often corrupt other unrelated variables, which is obviously dangerous and can cause any random behavior. Such bugs are often hard to track down. Stack overflows for example are such segmentation faults prone to overwrite adjacent variables, unless the error was caught by protection mechanisms.

If we look at the behavior of "bare metal" microcontroller systems without any OS and no virtual memory features, just raw physical memory - they will just silently do exactly as told - for example, overwriting unrelated variables and keep on going. Which in turn could cause disastrous behavior in case the application is mission-critical.

Why is it not recoverable?

Because the OS doesn’t know what your program is supposed to be doing.

Though in the "bare metal" scenario above, the system might be smart enough to place itself in a safe mode and keep going. Critical applications such as automotive and med-tech aren’t allowed to just stop or reset, as that in itself might be dangerous. They will rather try to "limp home" with limited functionality.

Why does this solution avoid that unrecoverable state? Does it even?

That solution is just ignoring the error and keeps on going. It doesn’t fix the problem that caused it. It’s a very dirty patch and setjmp/longjmp in general are very dangerous functions that should be avoided for any purpose.

We have to realize that a segmentation fault is a symptom of a bug, not the cause.

Why do I get segmentation fault here

To answer your questions. This is why you receive a segfault:

There is a fundamental difference between a string literal (such as what is declared with char *string="Test,string1,Test,string2:Test:string3";) and a character array, which is the referenced version using char[50].

To provide a different persective of what is going wrong, here is what happens during compilation.

In both scenarios, the constant string "Test,string1,Test,string2:Test:string3" is stored in the readonly data section of the binary. When you use char *string, you are assigning the location (pointer) of the constant string (in .rodata) to a variable on the stack. When you use char string[50] you are actually declaring an array of chars as storage on the stack, not a char pointer. The compiler actually performs this assignment in a different manner than what you may expect. In many cases, it will add a function call such as memcpy to initialize the character array. Something like this:

char string [50]
memcpy(string,"Test,string1,Test,string2:Test:string3",0x32);

This has the advantage of creating a local stack variable that can be manipulated through further functions such as strtok. However, you certainly cannot use the same functions to manipulate the original string in the readonly section of the binary. That is the fundamental difference.

Everything else mentioned by @Vlad from Moscow is also relevant.

Next question: Also, can segmentation fault cause damage to data on disk?

A segmentation fault occurs when an operation (read, write, execute) occurs in a memory segment that does not allow such operations. Most often, this occurs from attempting to read from or write to the location referenced by an invalid pointer. This is entirely a runtime concept. The fault is contained within the virtual memory of the process. Generally speaking, this will not cause harm to any secondary storage. There may exist edge cases (a segfault occurred after partially writing data to a file) where file in secondary storage may be corrupted, but the example you have shown is not such a case. To summarize, your disk should be fine unless a segfault occurs in the middle of a write to disk.

Why does this program cause a segmentation fault?

The situation you describe is known as "infinite recursion", and is described in this post.

In the mentioned post, main() is calling main(), calling main(), ...

In your case, a() is calling b(), calling a(), calling b(), ...

The mentioned post shows the effect of this on the stack and gives an idea on how this is handled in the memory of your computer (using assembly).

Unexpected Segmentation fault while debugger shows namespace without issues

Solution was said in the comments by Botje:
" Not sure if it is the cause of your problem, but your Vehicle::Vehicle(World * w) constructor does not fill in any of the fields. It creates a temporary Vehicle and then throws it away."

I just copied the content of the other constructor to actually construct the object.
This is not a very nice solution, i think. Since I have to copy code. If this can be avoided somehow, please tell me how.
(I first tried doing this = Vehicle(other constructor), but a constructor does not return anything.)

EDIT: It is called delegating constructors, or at least, I found the right way to do it in this question.

c++: variable to pointer, unexpected segmentation fault

This version with pointers will work

int main()
{
foo aa, bb;
foo* a = &aa;
foo* b = &bb;
...
}

The difference is that in this version the pointers are actually pointing at something. But I'm sure you'll agree there's no purpose to this code, it's better without the pointers.

Pointer variables are no different from other kinds of variables, if you want to use them, you have to give them values.



Related Topics



Leave a reply



Submit