views:

389

answers:

10

OK for whatever reason I'm having trouble causing a seg fault. I want to produce one so that I can use gdb to see how to debug one. I have tried both examples from the Wikipedia article yet neither work.

The first one:

char *s = "Hello World!";
*s = 'H';

And the second example:

int main(void) 
{
    main();
}

EDIT: I'm using Ubutnu 9.10 and g++ as my compiler. Can anyone show me some code that is guaranteed to segfault?

A: 
char * ptr = 0;
*ptr = 1;

Segmentation fault
stefanB
+2  A: 
int *hello = NULL;
printf(*hello);

or you can define a struct (say HelloWorld struct)

HelloWorld *myWorld = NULL;
myWorld->world = "hello";
tster
+5  A: 

Both of the things you do will produce "undefined behaviour" in C++ (well, calling main() is actually explicitly forbidden). There is no guarantee that they will cause seg faults - this will depend on a lot of things, but mostly the platform you are running on, which you haven't specified.

In fact, any suggested method of causing a seg fault may or may not work. This is because a seg fault is almost always associated with C++'s concept of undefined behaviour.

anon
It is undefined behavior from the language point of view, but the operating system probably defines the conditions under which a segmentation fault occurs, and you can force those condition in C++. (Example: `int *p = 0; while (true) *p++ = 10;` will at one point or another hit a memory segment that is not writable by the process, and under linux or macosx will trigger a segmentation fault)
David Rodríguez - dribeas
+2  A: 

Lots of ways to generate a segfault.

Like dereferencing a bad pointer:

char *s = (char *)0xDEADBEEF;
*s = 'a';
Anon.
`0xDEADBEEF` is a number. "Hello World" is a string. In this case, `s` ends up pointing to memory address `0xDEADBEEF`, which is (most likely) completely invalid. In the OP's example, `s` ends up containing the address of the string - if the compiler hasn't declared the memory as read-only, no error results if we try to write to it.
Anon.
+7  A: 

My one line flavor:

*(char *)0 = 0;
R Samuel Klatchko
Even that is not guaranteed to produce a segfault. It is just undefined behavior. Which may or may not work.
Martin York
@Martin - guaranteed on all platforms, no. Will this cause a segfault on Ubuntu Linux, yes.
R Samuel Klatchko
@R: You can't gurantee that! Why do you think Ubunt is so special! Relying on undefined behavior to do somthing special is just asking to be burn rather badly at some point down the road. Its described as un-defined for a reason. Just dont do it unless you explicitly know what will happen and you don't
Martin York
@Martin - if you would like to have a discussion, I'm glad to do that. But if you're going to insult me, I'm not going to waste any more time responding.
R Samuel Klatchko
I don't see any insults.
GMan
@R: Glad you took the time to respond to tell me you are not going to respond, that was very courteous of you :-) PS. If you mean the " and you don't" it is not the personal ("You don't know what you are doing") but rather the ("You can't know what will happen").
Martin York
@Martin - actually, I wrote I was not going to respond *more* if you were going to insult me. Since you've clarified your use of "and you don't", I'll rebut this.
R Samuel Klatchko
For platforms with memory management, Linux makes an access of unmapped pages generate a segfault. Ubuntu is only built for platforms with memory management. Linux does not map page 0. On Ubuntu 9.10, vm.mmap_min_addr defaults to 65535 so you can't accidentally map page 0. Therefore writing to address 0 will cause a segfault. Yes, if you override vm.mmap_min_addr and then mmap page 0 then writing to address 0 will not cause a segfault so I'll agree it's not 100% guaranteed to cause a segfault. But other then that, on the specific platform mentioned, when can this not cause a segfault.
R Samuel Klatchko
+1  A: 

The Wikipedia article actually lists three methods (one of which is a null pointer dereference); why didn't you try that one?

As for why the two examples you tried didn't, well, the correct answer as others have noted is that it's undefined behavior, so anything could happen (which includes not segfaulting). But one could speculate that the reason that the first form didn't fail for you is because your compiler or system is lax about memory protection. As for the second case, a tail-recursive-aware compiler conceivably could optimize the infinitely recursive main loop and not end up overflowing the stack.

jamesdlin
+1  A: 

For the first example, the compiler probably put the string in writable memory, so there is no seg fault when trying to change it.

For the second, the compiler may be optimizing the call away or may be optimizing the call itself away to just a jump (since it is a tail call), meaning the stack isn't actually growing with return addresses for each call, so you could recurse indefinitely.

But as Neil mentioned in his post, any of these things results in "undefined behavior", so the code is not required at runtime to generate a seg fault.

Michael
A: 

If you try to concatenate two constants... you'll get one... at least is a simple way...

strcat("a", "b");

=)

Juan Manuel
only if the literals are allocated in read-only memory. Which it apparently isn't in his case, or his string manipulation would've caused a segfault in the first place.
jalf
+13  A: 

It impossable to try and reliable do it dereferencing pointers.
This is because how the application handles memory can vary from compiler to compiler also across the same compiler with different options (debug/release mode handeled differently).

What you can do is explicitly raise the segfault using a signal:

#include <signal.h>

int main()
{
    raise(SIGSEGV);
}
Martin York
+1  A: 

Shortest segfault ever:

*(int*)0=0;
AndiDog
much shorter: `*(short*)0=0` lol
smerlin
@smerlin: +1 for subtle humor.
Martin York