I have never seen this but i had this thing in my mind!
stack memory error here could be a memory corruption also.
lets say there is a stack overflow in a c/c++ program.
does it create a core dump file?
It depends on the operating system and language runtime. I'll assume you're talking about some flavour of Unix/Linux, since you mention a core dump.
Typically, there will be some amount (perhaps a single page) of unmapped virtual memory beyond the stack. If you overflow by less than that amount, then the program will attempt to access that, giving a segmentation fault. If the program doesn't handle the signal, then it will abort; and if core dumps are enabled, then one will be produced. You may need to enable core dumps, perhaps using ulimit -c unlimited from the shell you use to launch the program.
If you overflow by a large amount, then you may instead overwrite some other part of the program's memory. If this happens, then all bets are off; the program could crash, or could continue in a corrupt state and cause any kind of damage at any point in the future.
That's assuming that, by "overflow" you mean using more stack memory than has been allocated by some combination of a deep call stack and large automatic objects. If you're talking about writing to the wrong part of the stack (e.g. by an out-of-bounds access to an automatic array), then you'll typically get random memory corruption rather than a segmentation fault; again, the program might shamble on in a corrupt state with unpredictable results.
Stack overflow does not create a core dump file always. If you are lucky, it is just a simple overrun of your stack, some local variables or buffers are overwritten. It might not cause any abnormal behavior of your program, and no core dump file.
However, if the stack overflow overwrites some local variables which are pointers, or the return address, when you use the pointer, which is now invalid address and points to unmapped memory page, or the program use the pointer to write to read-only pages, it causes the segmentation fault and the core dump file is created. Or the return address is overwritten, and the CPU returns to invalid addressing space or executes invalid code, it also causes the exception and a core file is created.
Related
For example when we call say, a recursive function, the successive calls are stored in the stack. However, due to an error if it goes on infinitely the error is 'Segmentation fault' (as seen on GCC).
Shouldn't it have been 'stack-overflow'? What then is the basic difference between the two?
Btw, an explanation would be more helpful than wikipedia links (gone through that, but no answer to specific query).
Stack overflow is [a] cause, segmentation fault is the result.
At least on x86 and ARM, the "stack" is a piece of memory reserved for placing local variables and return addresses of function calls. When the stack is exhausted, the memory outside of the reserved area will be accessed. But the app did not ask the kernel for this memory, thus a SegFault will be generated for memory protection.
Modern processors use memory managers to protect processes from each other. The x86 memory manager has many legacy features, one of which is segmentation. Segmentation is meant to keep programs from manipulating memory in certain ways. For instance, one segment might be marked read-only and the code would be put there, while another segment is read/write and that's where your data goes.
During a stack overflow, you exhaust all of the space allocated to one of your segments, and then your program starts writing into segments that the memory manager does not permit, and then you get a segmentation fault.
A stack overflow can manifest as either an explicit stack overflow exception (depending on the compiler and architecture) or as a segmentation fault, i.e., invalid memory access. Ultimately, a stack overflow is the result of running out of stack space, and one possible result of running out of stack space is reading or writing to memory that you shouldn't access. Hence, on many architectures, the result of a stack overflow is a memory access error.
The call stack is being overflowed, however the result of the overflowing is that eventually call-related values are pushed into memory that is not part of the stack and then - SIGSEGV!
I have been working with Google breakpad for crash reporting for sometime. One of the things that it emphasizes is that one should not allocate memory once a process has crashed. It says it isn't 'safe' to allocate memory in a process once it has crashed.
What exactly is the meaning of 'safe' here?
It's not safe because the standard library may be in a corrupt state, causing a second crash when you for more memory.
If you want to print something, do it w/o memory allocation (e.g. use local variables)
Once a process has crashed, the best you can hope for is learning what has happened before exiting the process for good. The "safety" is, therefore, reduced to your error reporting code not causing a crash of its own on top of the original crash. That is why your options at this point are limited: for example, trying to allocate memory is dangerous, because the original crash could have been caused by corrupted heap.
You really shouldn't be doing anything too complicated after a crash, lest you hang or have a crash in your crash code. The two main reasons are: locks and global variables. If your process crashed while holding a lock, and you need that lock for whatever you are doing after the crash, it'll either error off, or worse, hang. There are also lots of state information stored in global variables. Not just what's declared in your program, but also lots of things used by libraries and even the dynamic linker/loader. If any of those are bad, the result of calling a function that uses one of those globals is unpredictable.
I'm trying to understand how the objects (variables, functions, structs, etc) work in c++. In this case I see there are basically two ways of storing them: the stack and the heap. Accordingly, whenever the heap storage is used it needs to be dealocated manually, but if the stack is used, then the dealocation is automaticcally done. so my question is related to the kinds of problems that bad practice might cause the program itself or to the computer. For example:
1.- Let'suposse that I run a program with a recursion solution by using an infinite iteration of functions. Theoretically the program crashes (stack overflow), but does it cause some trouble to the computer itself? (To the RAM maybe or to the SO).
2.- What happens if I forget to dealocate memory on the heap. I mean, does it just cause trouble to the program or it is permanent to the computer in general. I mean it might be that such memory could not be used never again or something.
3.- What are the problems of getting a segmentation fault (the heap).
Some other dangers or cares relevant to this are welcome.
Accordingly, whenever the stack storage is used it needs to be
dealocated manually, but if the heap is used, then the dealocation is
automaticcally done.
When you use stack - local variables in the function - they are deallocated automatically when the function ends (returns).
When you allocate from the heap, the memory allocated remains "in use" until it is freed. If you don't do that, your program, if it runes for long enough and keep allocating "stuff", will use all memory available to it, and eventually fail.
Note that "stackfault" is almost impossible to recover from in an application, because the stack is no longer usable when it's full, and most operations to "recover from error" will involve using SOME stack memory. The processor typically has a special trap to recover from stack fault, but that lands insise the operating system, and if the OS determines the application has run out of stack, it often shows no mercy at all - it just "kills" the application immediately.
1.- Let'suposse that I run a program with a recursion solution by using an infinite iteration of functions. Theoretically the program
crashes (stack overflow), but does it cause some trouble to the
computer itself? (To the RAM maybe or to the SO).
No, the computer itself is not harmed by this in and of itself. There may of course be data-loss if your program wasn't saving something that the user was working on.
Unless the hardware is very badly designed, it's very hard to write code that causes any harm to the computer, beyond loss of stored data (of course, if you write a program that fills the entire hard disk from the first to the last sector, your data will be overwritten with whatever your program fills the disk with - which may well cause the machine to not boot again until you have re-installed an operating system on the disk). But RAM and processors don't get damaged by bad coding (fortunately, as most programmers make mistakes now and again).
2.- What happens if I forget to dealocate memory on the heap. I mean, does it just cause trouble to the program or it is permanent to the
computer in general. I mean it might be that such memory could not be
used never again or something.
Once the program finishes (and most programs that use "too much memory" does terminate in some way or another, at some point).
Of course, how well the operating system and other applications handle "there is no memory at all available" varies a little bit. The operating system in itself is generally OK with it, but some drivers that are badly written may well crash, and thus cause your system to reboot if you are unlucky. Applications are more prone to crashing due to there not being enough memory, because allocations end up with NULL (zero) as the "returned address" when there is no memory available. Using address zero in a modern operating system will almost always lead to a "Segmentation fault" or similar problem (see below for more on that).
But these are extreme cases, most systems are set up such that one application gobbling all available memory will in itself fail before the rest of the system is impacted - not always, and it's certainly not guaranteed that the application "causing" the problem is the first one to be killed if the OS kills applications simply because they "eat a lot of memory". Linux does have a "Out of memory killer", which is a pretty drastic method to ensure the system can continue to work [by some definition of "work"].
3.- What are the problems of getting a segmentation fault (the heap).
Segmentation faults don't directly have anything to do with the heap. The term segmentation fault comes from older operating systems (Unix-style) that used "segments" of memory for different usages, and "Segmentation fault" was when the program went outside it's allocated segment. In modern systems, the memory is split into "pages" - typically 4KB each, but some processors have larger pages, and many modern processors support "large pages" of, for examble, 2MB or 1GB, which is used for large chunks of memory.
Now, if you use an address that points to a page that isn't there (or isn't "yours"), you get a segmentation fault. This, typically will end the application then and there. You can "trap" segmentation fault, but in all operating systems I'm aware of, it's not valid to try to continue from this "trap" - but you could for example store away some files to explain what happened and help troubleshoot the problem later, etc.
Firstly, your understanding of stack/heap allocations is backwards: stack-allocated data is automatically reclaimed when it goes out of scope. Dynamically-allocated data (data allocated with new or malloc), which is generally heap-allocated data, must be manually reclaimed with delete/free. However, you can use C++ destructors (RAII) to automatically reclaim dynamically-allocated resources.
Secondly, the 3 questions you ask have nothing to do with the C++ language, but rather they are only answerable with respect to the environment/operating system you run a C++ program in. Modern operating systems generally isolate processes so that a misbehaving process doesn't trample over OS memory or other running programs. In Linux, for example, each process has its own address space which is allocated by the kernel. If a misbehaving process attempts to write to a memory address outside of its allocated address space, the operating system will send a SIGSEGV (segmentation fault) which usually aborts the process. Older operating systems, such as MS-DOS, didn't have this protection, and so writing to an invalid pointer or triggering a stack overflow could potentially crash the whole operating system.
Likewise, with most mainstream modern operating systems (Linux/UNIX/Windows, etc.), memory leaks (data which is allocated dynamically but never reclaimed) only affect the process which allocated them. When the process terminates, all memory allocated by the process is reclaimed by the OS. But again, this is a feature of the operating system, and has nothing to do with the C++ language. There may be some older operating systems where leaked memory is never reclaimed, even by the OS.
1.- Let'suposse that I run a program with a recursion solution by using an infinite iteration of functions. Theoretically the program crashes (stack overflow), but does it cause some trouble to the computer itself? (To the RAM maybe or to the SO).
A stack overflow should not cause trouble neither to the Operating System nor to the computer. Any modern OS provides an isolated address space to each process. When a process tries to allocate more data in its stack than space is available, the OS detects it (usually via an exception) and terminates the process. This guarantees that no other processes are affected.
2.- What happens if I forget to dealocate memory on the heap. I mean, does it just cause trouble to the program or it is permanent to the computer in general. I mean it might be that such memory could not be used never again or something.
It depends on whether your program is a long running process or not, and the amount of data that you're failing to deallocate. In a long running process (e.g. a server) a recurrent memory leak can lead to thrashing: after some time, your process will be using so much memory that it won't fit in your physical memory. This is not a problem per se, because the OS provides virtual memory but the OS will spend more time moving memory pages from your physical memory to disk than doing useful work. This can affect other processes and it might slow down the system significantly (to the point that it might be better to reboot it).
3.- What are the problems of getting a segmentation fault (the heap).
A Segmentation Fault will crash your process. It's not directly related to the usage of the heap, but rather to accessing a memory region that does not belong to your process (because it's not part of its address space or because it was, but it was freed). Depending on what your process was doing, this can cause other problems: for instance, if the process was writing to a file when the crash happened it's very likely that it will end up corrupt.
First, stack means automatic memory and heap means manual memory. There are ways around both, but that's generally a more advanced question.
On modern operating systems, your application will crash but the operating system and machine as a whole will continue to function. There are of course exceptions to this rule, but they're (again) a more advanced topic.
Allocating from the heap and then not deallocating when you're done just means that your program is still considered to be using the memory even though you're not using it. If left unchecked, your program will fail to allocate memory (out of memory errors). How you handle out-of-memory errors could mean anything from a crash (unhandled error resulting in an unhandled exception or a NULL pointer being accessed and generating a segmentation fault) to odd behavior (caught exception or tested for NULL pointer but no special handling case) to nothing at all (properly handled).
On modern operating systems, the memory will be freed when your application exits.
A segmentation fault in the normal sense will simply crash your application. The operating system may immediately close file or socket handles. It may also perform a dump of your application's memory so that you can try to debug it posthumously with tools designed to do that (more advanced subject).
Alternatively, most (I think?) modern operating systems will use a special method of telling the program that it has done something bad. It is then up to the program's code to decide whether or not it can recover from that or perhaps add additional debug information for the operating system, or whatever really.
I suggest you look into auto pointers (also called smart pointers) for making your heap behave a little bit like a stack -- automatically deallocating memory when you're done using it. If you're using a modern compiler, see std::unique_ptr. If that type name can't be found, then look into the boost library (google). It's a little more advanced but highly valuable knowledge.
Hope this helps.
My question has two parts:
Is it possible that, if a segfault occurs after allocating memory but before freeing it, this leaks memory (that is, the memory is never freed resulting in a memory leak)?
If so, is there any way to ensure allocated memory is cleaned up in the event of a segfault?
I've been reading about memory manamgement in C++ but was unable to find anything about my specific question.
In the event of a seg fault, the OS is responsible for cleaning up all the resources held by your program.
Edit:
Modern operating systems will clean up any leaked memory regardless of how your program terminates. The memory is only leaked for the life of your program. Most OS's will also clean up many other types of resources such as open files and socket connections.
Is it possible that, if a segfault occurs after allocating memory but
before freeing it, this leaks memory (that is, the memory is never
freed resulting in a memory leak)?
Yes and No: The process which crashes should be tiedied completely by the OS. However consider other processes spawned by your process: They might not get terminated completely. However usually these shouldn't take too many resources at all, but this may vary depending on your program. See http://en.wikipedia.org/wiki/Zombie_process
If so, is there any way to ensure allocated memory is cleaned up in
the event of a segfault?
In case the program is non critical (meaning there are no lives at stake if it crashes) I suggest fixing the segmentation fault. If you really need to be able to handle segmentation faults see the answer on this topic: How to catch segmentation fault in Linux?
UPDATE: Please note that despite the fact that it is possible to handle SIGSEGV signals (and continuning in program flow) it is not a secure way to rely on, since - as pointed out in the comments below - it is undefined behaviour meaning differen platforms/compilers/... may react differently.
So by any means possible fixing segmentation faults (as well as access violations on windows) should have first priority. Still using the suggested solution to handle signals this way must be thoroughly tested and if put in production code you must be aware of it and draw any consequences - which may vary and depend on your requirements so I will not name any.
The C++ standard does not concern itself with seg-faults (that's a platform-specific thing).
In practice, it really depends on what you do, and what your definition of "memory leak" is. In theory, you can register a handler for the seg-fault signal, in which you can do all necessary cleanup. However, any modern OS will automatically clear up a terminating process anyway.
One, there are resources the system is responsible for cleaning up. One of them is memory. You do not have to worry about permanently leaked RAM on a segfault.
Two, there are resources that the system is not responsible for cleaning up. You could write a program that inserts its pid into a database and removes it on close. That won't be removed on a segfault. You can either 1) add a handler to clean up that sort of non-system resources, or 2) fix the bugs in your program to begin with.
Modern operating systems separate applications' memory as to be able to clean up after them. The problem with segmentation faults is that they normally only occur when something goes wrong. At this point, the default behavior is to shut down the application because it's no longer functioning as expected.
Likewise, unless under some bizarre circumstance, your application has likely done something you cannot account for if it has hit a segmentation fault. So, "cleaning up" is likely practically impossible. It's not out of the realm of possibility to use memory carefully similar to transactional databases in order to guarantee an acceptable roll-back state, however doing so (and depending on how fine-grained of a level) may be beyond tedious.
A more practical version may be to provide your own sort of sandboxing between application components and reboot a component if it dies, restoring it to a acceptable previous saved state wholesale. That way you can flush all of its allocated memory and have it start from scratch. You still lose whatever data it hadn't saved as of the last checkpoint, however.
I've written some C++ code that runs perfectly fine on my laptop PC (compiled under both a Microsoft compiler and g++ under MinGW). I am in the process of porting it to a Unix machine.
I've compiled with both g++ and with Intel's ipcp on the Unix machine and in both cases, my program crashes (segfaults) after running for a while. I can run it for a short time without a crash.
When I debug, I find that the crash is happening when the program tries to copy an STL list - specifically, it happens when the program tries to allocate memory to create a new node in the list. And the error I get in the debugger (TotalView) is that "an allocation call failed or the address returned is null."
The crash does not always happen in the same place in the code each time I run it, but does always happen during an allocation call to create a node in an STL list. I don't think I'm running out of memory. I have a few memory leaks, but they're very small. What else can cause a memory allocation error? And why does it happen on the Unix machine and not on my PC?
UPDATE: I used MemoryScape to help debug. When I used guard blocks, the program ran through without crashing, further suggesting a memory issue. What finally worked to nail down the problem was to "paint" allocated memory. It turns out I was initializing a variable, but not setting it to a value before I used it as an array index. The array was therefore overrunning because it was using whatever garbage was in the variable's memory location -- often it was 0 or some other small number, so no problem. But when I ran the program long enough, it was more likely to hold a larger number and corrupt the heap when I wrote out of bounds of the array. Painting the allocated memory with a large number forced a segfault right at the line of code where I attempted to write a value in the array and I could see that large painted number being used as the array index.
This is likely caused by heap corruption - elsewhere in the code, you're overwriting freed memory, or writing to memory outside the bounds of your memory allocations (buffer overflows, or writing before the start of allocated memory). Heap corruption typically results in crashes at an unrelated location, such as in STL code. Since you're on a unix platform, you should try running your program under valgrind to try to identify the original heap corruption.
This sounds like a corruption of the dynamic memory allocation data structures, which is often caused by other, unrelated code. This type of bug is notorious for being hard to find and reproduce without external tools, because any change in memory layout can mask it. It probably worked through luck in the Windows version.
Memory debuggers are great tools to catch such corruption. valgrind, dmalloc and efence are very good alternatives to check the correctness of your program.
I have a few memory leaks, but they're very small.
Well, if you run it for a while, then it ends up being a lot of memory. That's kind of the thing about leaks. You should log your memory usage at the point of the crash to see if there was any memory available.