Can segmentation fault be caused by exhaustion of memory ? - c++

I am solving a problem on codechef.
I have coded the algorithm of the problem and it runs fine on the test cases. Although, when I run it on codechef(online), it throws segmentation fault.
I have double checked that, I am not accessing any inaccessible memory locations, although I suspect that my program could have taken up huge amount of memory.
So, my question is that Can segmentation fault be thrown, when there is no more memory available for the program to execute. Something like OutOfMemoryException in C#

This depends on the way you allocate memory and whether you check for errors when doing so. E.g. malloc would return NULL on an out-of-memory condition. A failure to check that may lead to dereferencing NULL which would result in a segmentation fault. If you use new of C++, it would throw an exception instead.
In reality though when a program does excessive memory allocations it usually gets the system RAM overcommitted and its process is killed by an OOM killer before its malloc would start returning NULLs - unless most of the allocated memory is actually unused.

As Kerrek mentioned in the comments an excessive usage of automatic storage or a call stack which is too deep can cause a SEG-fault e.g (on coliru):
void foo(){ foo(); }
int main() {
foo();
return 0;
}
or (on coliru):
#include <iostream>
int main()
{
int a[50000000];
std::cout << a[500];
}
So to sum it up you have to be aware of your systems limitations, for example some recursive brute force solutions are sometimes theoretically OK and should work but are rather impractical (yes, this is a vague example but the OP did not mention what problem is being solved nor how so I wanted to give the above at least some context...).

There are actually two situations
1. You try to allocate too much from the call stack, then you'll receive a signal. An exception can't be caught
int main() {
try {
std::array<int,10000000> arr;
cout << arr[40] << endl;
}
catch(const std::exception& e) {
cout << e.what() << endl;
}
return 0;
}
2. You try to allocate too much dynamic memory, then you'll receive an exception
int main() {
try {
std::vector<int> arr;
arr.resize(1000000000);
cout << arr[40] << endl;
}
catch(const std::exception& e) {
cout << e.what() << endl;
}
return 0;
}
You can try it live on ideone.

Related

C++ - Transactional memory: exact meaning of atomic_commit?

Context:
I was reading the Transactional memory reference.
Some info are really unclear to me.
I run the code below in godbolt and I have a sense of what should happen but I want some confirmation or explanation of what is really expected to happen, not what I think should happen.
In the atomic_commit case:
If an exception is thrown, the transaction is committed normally.
That line raises some questions:
auto f() -> std::optional<int> {
static int i = 0;
std::optional<int> p;
atomic_commit {
//some memory ops happen here
++i;
throw std::runtime_error("I decide to fail here, for some reason");
p = i;
return p; // commit transaction
}
return std::nullopt;
}
int main() {
for (int retries = 0 ; retries < 10 ; ++retries) {
try {
auto r = f();
if (r) {
std::cout << r.value() << std::endl;
} else {
std::cout << "nope" << std::endl;
}
} catch (...) {
//handle the exception and maybe retry.
}
}
}
Question:
What happens exactly to the already registered data ? Is it taken back?
If two threads try to write at the same address, and the first one
failed to do so, what happens to the second? is the data corrupted?
In the case no exception is thrown, and two threads try to write in the same
address, what happens exactly?
As an added info, I mostly use the latest gcc.
Other thoughts:
On the other hand, the atomic_cancel seems to have an interesting behavior:
the values of all memory locations in the program that were modified by side effects of the operations of the atomic block are restored to the values they had at the time the start of the atomic block was executed, and the exception continues stack unwinding as usual
That would mean that all the data is copied first (may be faster than a lock).
It is the most natural behavior to me, except for the part that calling std::abort is quite rude.
But it doesn't matter, it is not always implemented anyway(gcc..).
Thanks

How to catch or log memory deallocation errors?

Consider the following program:
#include <iostream>
int main()
{
try
{
auto b = malloc(69);
free(b);
free(b);
}
catch (...)
{
}
std::cout << "Hello, world!" << std::endl;
}
It will never print "Hello, world!" because the exception that free causes the second time it is called, is not catchable. A similar thing can happen with operator delete in C++.
Now, I don't want to catch these errors, per-se, but not even SetUnhandledExceptionFilter gets me a call. My program just dies and I have no logging to work with; my only hope of finding these kinds of bugs is attaching a debugger hoping I can reproduce whatever happened.
So, is there anything I can do within my program to get a notification similar to what the debugger seems to be getting?

Catch c++ exception by allocating c memory error

I allocate a char pointer for receiving data. When the data is too large, I'll receive the Segmentation fault (core dumped). I try to use a try catch block to catch the exception to avoid this kind of error, but the same error still shows. How do I catch this kind of exception?
#include<iostream>
using namespace std;
void setmemory(char* p, int num)
{
p=(char*)malloc(num);
}
void test(void)
{
char* str = NULL;
setmemory(str,1);
try{
strcpy(str,"hello");
cout << "str:" << str << endl;
} catch (...) {
str = NULL;
cout << "Exception occured!" << endl;
}
}
int main()
{
test();
return 0;
}
Generally catching of Segmentation Fault is bad idea because you have no guaranty that any data in your program still valid. So you cannot just intercept SIGSEGV signal and do you work as usual.
See more details here:
How to catch segmentation fault in Linux?
You cannot catch segmentation fault through exception... Exceptions are not designed to catch signals. For these cases you need special handling like calling signal handler etc...
Although there is a way to convert these signals into exceptions in C++. Following link would illustrate on this topic:-
https://code.google.com/p/segvcatch/
Example given in this:-
try
{
*(int*) 0 = 0;
}
catch (std::exception& e)
{
std::cerr << "Exception catched : " << e.what() << std::endl;
}
Anyway after getting segmentation fault it's better to go for debugging rather than continue with current execution and later be transported to realm of undefined behavior.
You cannot catch a Segmentation fault in C++. A seg fault is a result of memory corruption due to a bad operation run by your program. At that point, the operating system has taken control of your program. You don't want to keep a program running after a seg fault because the state is unstable. You as the programmer need to avoid seg faults.
If the code you posted is your actual code, even if you allocated enough space, your code will not work correctly.
void setmemory(char *p, int num)
{
p=(char*)malloc(num);
}
int main()
{
char* str = NULL;
setmemory(str,1);
//...
strcpy(str,"hello");
We can stop right there. You are attempting to copy "hello" to a NULL pointer. You are not setting str to the allocated space, even though the setmemory function was called.
The proper way to do this (I will use the malloc, even though I don't recommend it) would be:
void setmemory(char *&p, int num)
{
p=(char*)malloc(num);
}
You need to pass the pointer by reference, otherwise p acts as a temporary variable, so setting p within the function will not propagate back to the caller.

How to catch exception without throw

There is a CRASH in Function() due to some exceptions so, throw X would not be called. In this case how to call catch block to handle exceptions?
NOTE: we can't modify the code in Function() definition
Sample code:
cout << "Before try \n";
try {
abc->Function(); //Here is CRASH
throw x;
cout << "After throw (Never executed) \n";
}
catch (...) {
cout << "Exception Caught \n";
}
cout << "After catch (Will be executed) \n";
So can anyone help me out for this?
A "CRASH" is not an exception. It is Undefined Behaviour. Absolutely anything could have happened. You are lucky that the system detected it. It could have formatted your disk or summoned daemons out of your nose. Instead the system is only shutting down the process to prevent further damage.
The system might even be so kind as to let you define what to do instead of shutting down the process. The way to define it is system specific. In Unix, you need to install signal handler (the advanced way), in Windows you use structural exceptions.
But the problem is that if the function crashed, there is no way to tell how big mess it left the memory of the process in. You really have to fix the crash. A crash is always a bug.
The fact that a crash is inside that function does not automatically mean the bug is in that function. Most crashes I've seen happened in standard library functions, but they were not bugs in standard library. They were caused by incorrect use of those functions, or sometimes incorrect use of something different much earlier in the program. Because when you invoke Undefined Behaviour, there's no telling when it will cause a crash. Especially buffer overruns and writes to uninitialized pointers tend to cause crashes eventually when some unrelated code wants to use the variable that was overwritten.
That said if the bug is indeed in that function and you can't modify it, you will have to get somebody who can or find an alternative that works better. Because there's no way the program is going to work correctly otherwise.
There's an aditional '}' in the try block in your code. Not sure whether that was an error in typing the code or from another higher level block.
The catch(...){} block will be executed when any unhandled exception is thrown inside the try {} block. It doesn't matter whether the exceptions are thrown directly under the block or somewhere deep down in other function calls in the block.
cout << "Before try \n";
try
{
abc->Function1(); //A potential for crash
abc->Function2(); //Another potential for crash
abc->Function3(); //Another potential for crash
// Do some checks and throw an exception.
throw x;
cout << "After throw (Never executed) \n";
}
catch (...)
{
// This will catch all unhandled exceptions
// within the try{} block. Those can be from
// abc->Function1(), abc->Function2(), abc->Function3(),
// or the throw x within the block itself.
cout << "Exception Caught \n";
}
cout << "After catch (Will be executed) \n";
Hope that is helpful.
Here us the meaning of try and catch
try {
//[if some ABC type exception occur inside this block,]
}catch (ABC) {
//[Then, Do the things inside this block.]
}
So
after the exception occur in your abc->Function(); flow will directly jump in to catch block so write there what you need to do. as example.
try {
abc->Function(); //Here is CRASH
throw x;
cout << "After throw (Never executed) \n";
}catch (Exception ex) {
cout << "Exception Caught \n";
throw ex;
}
actually throw x; doesn't have any use here. because if your abc->Function(); worked fine, then it will throw an exception. so just remove that line.
the code you have written works exactly true . the compiler when see the throw command every where in the try{} it will go to the catch(){} so the cout << "After throw (Never executed) \n"; won't execute and then the code after the catch(){} will execute
for reading more about this case here is the link trycatch
If you got exception ,
abc->Function(); //Here is CRASH
You will enter in catch(...) block.
If you are using Windows OS, for OS generated exceptions you also need to use __try/__catch

intermixing c++ exception handling and SEH (windows)

I have a function in which I call getaddrinfo() to get an sockaddr* which targets memory is allocated by the system.
As many may know, you need to call freeaddrinfo() to free the memory allocated by getaddrinfo().
Now, in my function, there are a few places, where I may throw an exception, because some function failed.
My first solution was to incorporate the freeaddrinfo() into every if-block.
But that did look ugly for me, because I would have had to call it anyways before my function returns, so I came up with SEH`s try-finally...
But the problem I encountered is, that it is not allowed to code the throw-statements into the __try-block
Then, I read on the msdn and tried to swap the throw-statements into the helper function called from within the __try-block... and voila, the compiler didnĀ“t moan it anymore...
Why is that? And is this safe? This does not make sense to me :/
Code:
void function()
{
//...
addrinfo* pFinal;
__try
{
getaddrinfo(..., &pFinal);
//if(DoSomething1() == FAILED)
// throw(exception); //error C2712: Cannot use __try in functions that require object unwinding
//but this works
Helper();
//...
}
__finally
{
freeaddrinfo();
}
}
void Helper()
{
throw(Exception);
}
EDIT:
tried the following and it works with throwing an integer, but does not when i use a class as an exception:
class X
{
public:
X(){};
~X(){};
};
void Helper()
{
throw(X());
}
void base()
{
__try
{
std::cout << "entering __try\n";
Helper();
std::cout << "leaving __try\n";
}
__finally
{
std::cout << "in __finally\n";
}
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
base();
}
catch(int& X)
{
std::cout << "caught a X" << std::endl;
}
std::cin.get();
return 0;
}
Why? :/
You can't mix the two exception types. Under the covers, C++ exceptions use SEH and your SEH exception handler could mess up the exception propogation logic. As a result, the C++ compiler won't allow you to mix them.
PS: Structured Exception Handling is almost always a VERY bad idea. Internally Microsoft has banned the use of SEH except in very limited circumstances. Any component that does use structured exception handling is automatically subject to intense code reviews (we have tools that scan code looking for its use to ensure that no cases are missed).
The problem with SEH is that it's extremely easy to accidentally introduce security vulnerabilities when using SEH.
You could wrap the addrinfo in a class that calls getaddrinfo in the constructor and freeaddrinfo in its destructor.
That way it will always be freed, whether there is an exception thrown or not.
catch(int& X)
{
std::cout << "caught a X" << std::endl;
}
That doesn't catch an X, it catches an int&. Since there is no matching catch block, the exception is uncaught, stack unwinding doesn't occur, and __finally handlers don't run.
You can put catch (...) in your thread entrypoint (which is main() for the primary thread) in order to make sure that stack unwinding occurs, although some exceptions are unrecoverable, that's never true of a C++ exception.