24

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?

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Bob Dylan
  • 4,393
  • 9
  • 40
  • 58

10 Answers10

51

It impossible 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 handled differently).

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

#include <signal.h>

int main()
{
    raise(SIGSEGV);
}
jacknad
  • 13,483
  • 40
  • 124
  • 194
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • It is incorrect to state that "It impossable to try and reliable do it dereferencing pointers." - you can use tests and analysis of your code to establish that it segfaults reliably. – user1976 Jun 09 '16 at 09:57
  • @user1976: Apparently you don't understand what undefined behavior means. – Martin York Jun 09 '16 at 15:54
  • @ Loki Astari: Undefined behaviour means that (very) recent compilers (clang being the worst offender) feel free to be annoying and delete your code. However, that doesn't mean that the generated code can not be relied upon to exhibit well defined behaviour. You simply need to rely another method, outside of the C++ standard, to guarantee this. – user1976 Jun 09 '16 at 16:43
  • 2
    @user1976: Sure you can reliably do it using lots of things. But you can not reliably do it using undefined behavior. And undefined behavior is never well defined. As dereferencing a valid pointer is well defined when the pointer is valid you can crash this way. Also dereferencing a nullptr or an invalid pointer is undefined behavior so you can not get well defined behavior from that. So my statement stands. – Martin York Jun 09 '16 at 21:45
  • @ Loki Astari: I would agree with the statement that - you can not write portable C++ code that can be guaranteed to segfault. However, your statement is that - you can't reliably cause segfaults by dereferencing pointers - that's incorrect, dereferencing pointers is exactly what causes segfaults and it is very reliable. – user1976 Jun 10 '16 at 07:38
  • @user1976: Then you have a different definition of reliable than me (and the rest of the engineering community). Reliable means it does the same thing **everywhere**. An invalid program by definition is not reliable,. Mike Drop. Boom. – Martin York Jun 10 '16 at 13:58
  • @ Loki Astari: Yes, I think that we are disagreeing over terminology. I think that reliable implies - exhibits the intended behaviour on the supported platforms - that's obviously different to your definition. – user1976 Jun 10 '16 at 15:15
27

My one line flavor:

*(char *)0 = 0;
R Samuel Klatchko
  • 74,869
  • 16
  • 134
  • 187
  • 4
    Even that is not guaranteed to produce a segfault. It is just undefined behavior. Which may or may not work. – Martin York Jan 11 '10 at 23:10
  • 3
    @Martin - guaranteed on all platforms, no. Will this cause a segfault on Ubuntu Linux, yes. – R Samuel Klatchko Jan 11 '10 at 23:18
  • @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 Jan 12 '10 at 00:37
  • @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 Jan 12 '10 at 00:57
  • @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 Jan 12 '10 at 01:22
  • @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 Jan 12 '10 at 02:03
  • 10
    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 Jan 12 '10 at 02:04
  • @RSamuelKlatchko: Seems like you can map page zero 0. And it is common enough hacking problem. http://blog.cr0.org/2009/06/bypassing-linux-null-pointer.html – Martin York Jun 09 '13 at 14:51
  • 2
    @RSamuelKlatchko the problem is that compiler knows that it is an undefined behaviour so it may assume it will never happen and code is unreachable. In general it means that there are multiple possible optimizations which will result in the code above not causing segfault regardless of the value of `vm.mmap_min_addr`. – Maciej Piechotka Aug 18 '14 at 09:21
7

Shortest segfault ever:

*(int*)0=0;
AndiDog
  • 68,631
  • 21
  • 159
  • 205
6

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.

  • 4
    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 Jan 11 '10 at 23:24
2
int *hello = NULL;
printf(*hello);

or you can define a struct (say HelloWorld struct)

HelloWorld *myWorld = NULL;
myWorld->world = "hello";
tster
  • 17,883
  • 5
  • 53
  • 72
2

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
  • 54,279
  • 5
  • 125
  • 144
1
char * ptr = 0;
*ptr = 1;

Segmentation fault
stefanB
  • 77,323
  • 27
  • 116
  • 141
1

Lots of ways to generate a segfault.

Like dereferencing a bad pointer:

char *s = (char *)0xDEADBEEF;
*s = 'a';
Anon.
  • 58,739
  • 8
  • 81
  • 86
  • `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. Jan 11 '10 at 22:40
  • 4
    Try 0xBADBADBAD - really, really, really bad – user1976 Jun 14 '16 at 17:22
1

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
  • 81,374
  • 13
  • 159
  • 204
1

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

strcat("a", "b");

=)

Juan Manuel
  • 178
  • 12
  • 1
    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 Jan 11 '10 at 22:53
  • Actually, strcat("seg", "fault"); is guaranteed to produce a segfault. – user1976 Jun 15 '16 at 14:13