views:

320

answers:

6

This is a mad-hack, but I am trying to deliberately cause a segfault at a particular point in execution, so valgrind will give me a stack trace.

If there is a better way to do this please tell me, but I would still be curious to know how to deliberaly cause a segfault, and why my attempt didn't work.

This is my failed attempt:

long* ptr = (long *)0xF0000000;
ptr = 10;

I thought valgrind should at least pick up on that as a invalid write, even if it's not a segmentation violation. Valgrind says nothing about it.

Any ideas why?

EDIT

Answer accepted, but I still have some up-votes for any suggestions for a more sane way to get a stack trace...

+4  A: 

Are you missing a * as in *ptr = 10? What you have won't compile.

If it does, somehow, that of course won't cause a seg-fault, since you're just assigning a number. Dereferencing might.

Assuming dereferencing null on your OS results in a segfault, the following should do the trick:

inline void seg_fault(void)
{
    volatile int *p = reinterpret_cast<volatile int*>(0);
    *p = 0x1337D00D;
}
GMan
The * is directly next to the type "long*"
Joel
On the next line.
GMan
I still haven't decided which form I prefer - "long* ptr", "long *ptr", "long * ptr"
Joel
That was it. Thanks.
Joel
How did that compile, then? What compiler are you using?
GMan
Joel: I prefer "long* ptr"
Steve Lacey
C Pointer Style: http://stackoverflow.com/questions/377164/whats-your-preferred-pointer-declaration-style-and-why/378389#378389
jleedev
+2  A: 

Are you on x86? If so then there is actually an opcode in the CPU that means "invoke whatever debugger may be attached". This is opcode CC, or more commonly called int 3. Easiest way to trigger it is with inline assembly:

inline void debugger_halt(void)
{
#ifdef MSVC
   __asm int 3;
#elif defined(GCC)
   asm("int 3");
#else
#pragma error Well, you'll have to figure out how to do inline assembly 
              in your compiler
#endif
}

MSVC also supports __debugbreak() which is a hardware break in unmanaged code and an MSIL "break" in slow code.

Crashworks
+2  A: 

Wouldn't it be better to send sig SEGV (11) to the process to force a core dump?

piotr
Generally, you can't know the exact point during execution (upon which you want to send SIGSEGV) from outside the process.
Michael Foukarakis
The process can send SIGSEGV to itself: `kill(getpid(), SIGSEGV);`
mark4o
+3  A: 

Sorry for mentioning the obvious but why not use gdb with a breakbpoint and then use backtrace?

(gdb) b somewhere
(gdb) r
(gdb) bt
eyalm
That's what I was thinking, but I'm not experienced enough on gdb to know how. :)
GMan
+3  A: 

Just call 'abort()'. It's not a segfault but it should generate a core dump.

Kristof Provost
A: 

As mentioned in other answers you can just call abort() if you want to abnormally terminate your program entirely, or kill(getpid(), SIGSEGV) if it has to be a segmentation fault. This will generate a core file that you can use with gdb to get a stack trace or debug even if you are not running under valgrind.

Using a valgrind client request you can also have valgrind dump a stack trace with your own custom message and then continue executing. The client request does nothing when the program is not running under valgrind.

#include <valgrind/valgrind.h>
...
VALGRIND_PRINTF_BACKTRACE("Encountered the foobar problem, x=%d, y=%d\n", x, y);
mark4o