Segmentation fault in linux program

What is a segmentation fault?

In Ubuntu I have faced the segmentation fault error many times. What is a segmentation fault and when does it occur?

Just to cover it up: I had a similar problem, whereas my segfaults were not reliably reproduceable and they came from (almost) random applications. Found out that most likely my memory is broken. So if quite any program causes segfaults, one might have a closer look at the RAM.

3 Answers 3

An error saying segmentation fault (or segfault, or SIGSEGV) in Ubuntu and other Unix-like operating systems, or saying general protection fault in Windows, is when a program attempts to access a part of memory that cannot be accessed, or which the program is prohibited from accessing. A segmentation fault is a kind of program crash, that is, an abnormal termination of a program. See the Wikipedia articles on crashes, memory protection, segmentation fault, general protection fault, and SIGSEGV for more information (and a more textured understanding of the topic than is presented here).

A segmentation fault is almost always due to a bug in the program where it occurs. I am guessing most or all of your segmentation faults are happening from the same application. Please provide more details about the circumstances under which segmentation faults are happening on your machine, and what program is crashing. Please also provide the full and exact text of the error message you’re receiving and any other messages that appear before it. This should make it possible for us to provide detailed advice specific to your problem (rather than just general information about what a segmentation fault is).

The best way for you to provide this information is for you to edit your question to include it. Alternatively, if you want this question to be just about segmentation faults in general, you could post a new question to ask about what specifically is causing your segmentation faults (if you do this, make sure to provide all these details in your new question).

Источник

How to catch segmentation fault in Linux?

I need to catch segmentation fault in third party library cleanup operations. This happens sometimes just before my program exits, and I cannot fix the real reason of this. In Windows programming I could do this with __try — __catch. Is there cross-platform or platform-specific way to do the same? I need this in Linux, gcc.

Читайте также:  Make tar archive linux

5 Answers 5

On Linux we can have these as exceptions, too.

Normally, when your program performs a segmentation fault, it is sent a SIGSEGV signal. You can set up your own handler for this signal and mitigate the consequences. Of course you should really be sure that you can recover from the situation. In your case, I think, you should debug your code instead.

Back to the topic. I recently encountered a library (short manual) that transforms such signals to exceptions, so you can write code like this:

Didn’t check it, though. Works on my x86-64 Gentoo box. It has a platform-specific backend (borrowed from gcc’s java implementation), so it can work on many platforms. It just supports x86 and x86-64 out of the box, but you can get backends from libjava, which resides in gcc sources.

Throwing from a signal handler is a very dangerous thing to do. Most compilers assume that only calls can generate exceptions, and set up unwind information accordingly. Languages that transform hardware exceptions into software exceptions, like Java and C#, are aware that anything can throw; this is not the case with C++. With GCC, you at least need -fnon-call-exceptions to ensure that it works–and there is a performance cost to that. There is also a danger that you’ll be throwing from a function without exception support (like a C function) and leak/crash later.

The library is now in github.com/Plaristote/segvcatch, but I couldn’t find the manual or compile it. ./build_gcc_linux_release gives several errors.

Here’s an example of how to do it in C.

#include #include #include #include void segfault_sigaction(int signal, siginfo_t *si, void *arg) < printf("Caught segfault at address %p\n", si->si_addr); exit(0); > int main(void) < int *foo = NULL; struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction)); sigemptyset(&sa.sa_mask); sa.sa_sigaction = segfault_sigaction; sa.sa_flags = SA_SIGINFO; sigaction(SIGSEGV, &sa, NULL); /* Cause a seg fault */ *foo = 1; return 0; >

@TimSeguine: that’s is not true. You just need to make sure you know what you are doing. signal(7) lists all async-signal-safe functions that can be used with relatively little care. In the example above it is also completely safe because nothing else in the program is touching stdout but the printf call in the handler.

Читайте также:  List volume in linux

@stefanct This is a toy example. Virtually any non-toy program is going to hold the lock on stdout at some point. With this signal handler, the worst that can probably happen is a deadlock on segfault, but that can be bad enough if you currently have no mechanism to kill rogue processes in your use case.

according to 2.4.3 Signal Actions, calling printf from within a signal handler which is called as a result of an illegal indirection, whether the program is multithreaded or not is just plain undefined behavior period.

@TylerDurden First of all, I printf out of exceptions all the time. So you have low standards for the code you write, and you publicly attach your name to that fact. I’m not sure why you’re proud of that, but OK. Secondly your idea that printf uses the heap is totally wrong and you would know that if actually read the source code to a typical printf function. ORLY. You just might want to take your own advice about reading source code before posting something.

For portability, one should probably use std::signal from the standard C++ library, but there is a lot of restriction on what a signal handler can do. Unfortunately, it is not possible to catch a SIGSEGV from within a C++ program without introducing undefined behavior because the specification says:

  1. it is undefined behavior to call any library function from within the handler other than a very narrow subset of the standard library functions ( abort , exit , some atomic functions, reinstall current signal handler, memcpy , memmove , type traits, std::move , std::forward , and some more).
  2. it is undefined behavior if handler use a throw expression.
  3. it is undefined behavior if the handler returns when handling SIGFPE, SIGILL, SIGSEGV

This proves that it is impossible to catch SIGSEGV from within a program using strictly standard and portable C++. SIGSEGV is still caught by the operating system and is normally reported to the parent process when a wait family function is called.

You will probably run into the same kind of trouble using POSIX signal because there is a clause that says in 2.4.3 Signal Actions:

The behavior of a process is undefined after it returns normally from a signal-catching function for a SIGBUS, SIGFPE, SIGILL, or SIGSEGV signal that was not generated by kill() , sigqueue() , or raise() .

A word about the longjump s. Assuming we are using POSIX signals, using longjump to simulate stack unwinding won’t help:

Although longjmp() is an async-signal-safe function, if it is invoked from a signal handler which interrupted a non-async-signal-safe function or equivalent (such as the processing equivalent to exit() performed after a return from the initial call to main() ), the behavior of any subsequent call to a non-async-signal-safe function or equivalent is undefined.

This means that the continuation invoked by the call to longjump cannot reliably call usually useful library function such as printf , malloc or exit or return from main without inducing undefined behavior. As such, the continuation can only do a restricted operations and may only exit through some abnormal termination mechanism.

Читайте также:  Linux операционная система вход

To put things short, catching a SIGSEGV and resuming execution of the program in a portable is probably infeasible without introducing undefined behavior. Even if you are working on a Windows platform for which you have access to Structured exception handling, it is worth mentioning that MSDN suggest to never attempt to handle hardware exceptions: Hardware Exceptions.

At last but not least, whether any SIGSEGV would be raised when dereferencing a null valued pointer (or invalid valued pointer) is not a requirement from the standard. Because indirection through a null valued pointer or any invalid valued pointer is an undefined behaviour, which means the compiler assumes your code will never attempt such a thing at runtime, the compiler is free to make code transformation that would elide such undefined behavior. For example, from cppreference,

Here the true path of the if could be completely elided by the compiler as an optimization; only the else part could be kept. Said otherwise, the compiler infers foo() will never receive a null valued pointer at runtime since it would lead to an undefined behaviour. Invoking it with a null valued pointer, you may observe the value 0 printed to standard output and no crash, you may observe a crash with SIGSEG, in fact you could observe anything since no sensible requirements are imposed on programs that are not free of undefined behaviors.

Источник

Оцените статью
Adblock
detector