I am writing a C++ code in the ROOT platform. I am getting the following error:
*** Break *** segmentation violation
gdb not found, need it for stack trace
Root > Function main() busy flag cleared
I just want to know what this means (in general).
Generally, "segmentation violation" means you accessed a piece of memory that wasn't allocated to you. Usually a stray pointer is the reason for that.
The remaining is some Linux-specific message concerning a missing gdb (which would be helpful to understand the problem).
Typically that means you have written to (or maybe read) memory you don't have permission on. Either it's just invalid memory or (if the platform supports such a concept) it's outside of the memory you own.
A common cause of this is freeing a pointer but then using it again.
Foo * pFoo = new Foo();
pFoo->Bar(); // should be fine.
delete pFoo; // pFoo now points to memory that may or may not still be an actual Foo.
pFoo->Bar(); // undefined behavior.
Related
Typically, if memory issue occurred in calling routine "free", a program will stop immediately with error message telling details of the error. Now assume "free" is called in a "try" block. If an error occurred with the call, will the program stop immediately with an error message, or will the program completes execution of the "try" block before exiting with error message?
free can't error out without some preexisting problem in your code occurring, almost certainly a result of undefined behavior. Once you're in the land of nasal demons, there are no guarantees. free doesn't have a concept of exceptions (it's a C function, no C++ features), or even error return codes; if you corrupt your heap, the program is already screwed, and what comes next can be anything. In practice, I'd expect one of four possibilities:
free doesn't notice the corrupted heap, and just makes things worse silently (try block continues running, because it doesn't realize anything is wrong)
free notices the corrupted heap, and the program dies immediately (no try/catch handling)
free is operating on a pointer to an invalid/unallocated region of memory, and you die with a segfault, bus error, etc. (again, no try/catch handling)
The pointer is to allocated memory that's not part of the heap; behaves like #1 or #2 depending on how "heap-like" it happens to look to the code.
My Qt5 app crashes when I hit the close window returning:
MyApp(28741,0x7fff7aa73000) malloc: *** error for object 0x7fc40bc8e300: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
The program has unexpectedly finished.
Classic approach to recover it, I guess, is to disable application modules (should I say parts of it, when things are not so well organized) systematically until the problem appears.
Is there some (more) intelligent way to solve this issue?
From what has been returned the problem is obvious, there is pointer somewhere being deleted (at least) two times. But were is this thing hiding?
What can I do with 28741,0x7fff7aa73000? And with 0x7fc40bc8e300? Can I use those to find something in Qt Creator 4 on Mac?
Because the app crash on close it means the problem is in a destructor?
From what has been returned the problem is obvious, there is pointer somewhere being deleted (at least) two times. But were is this thing hiding?
Not exactly; what you say is normally signaled as a "double free"; this seems more like somebody is passing to free something that never came from malloc.
To pinpoint it, do as the message says:
*** set a breakpoint in malloc_error_break to debug.
(or really, even just run it under a debugger; normally on Linux it does break into the debugger at the top of the stack when the program is aborted)
Once the breakpoint is hit, walk up the call stack and see what pointer is being freed, and try to find out why it is being freed when it doesn't actually come from malloc.
The fact that the address is "big" (0x7fc40bc8e300) tells that it probably comes from the stack (if OS X is anything like Linux, the heap is "down" in memory, the stack is at the opposite side of the virtual address space), so probably it's just as simple as somebody passing to free or delete an address that comes from the stack. This often happens when you erroneously pass a stack-allocated object to some method that wants to take ownership of it and free it with free or delete when it isn't needed anymore.
Also, running valgrind never hurts, but I doubt that in this case it can be of any help - you don't seem to be dealing with an invalid pointer (which it would detect at the first read/write), but you have a valid non-heap-allocated pointer that is being incorrectly deallocated with free. It will probably detect it at the same time as free itself.
I met such a C++ quiz: what would happen if a pointer is deleted twice?
A) it can abort the program
B) it can cause a failure
C) it can cause an error
D) it can cause a trap
and the answer is D.
I was a bit lost, what does "trap" mean? is it a special term in C++?
It doesn't mean anything in C++. It could mean an operating-system level error (such as a Posix signal), but without context I can't say.
The correct answer is that it causes undefined behaviour; but all the answers could be taken to be correct since undefined behaviour could cause any of these things to happen.
I shall simply directly quote the Wikipedia article on traps:
In computing and operating systems, a trap, also known as an exception or a fault, is typically[NB 1][1] a type of synchronous interrupt typically caused by an exceptional condition (e.g., breakpoint, division by zero, invalid memory access). A trap usually results in a switch to kernel mode, wherein the operating system performs some action before returning control to the originating process. A trap in a system process is more serious than a trap in a user process, and in some systems is fatal. In some usages, the term trap refers specifically to an interrupt intended to initiate a context switch to a monitor program or debugger.
This is highly generalised terminology and is not defined by C++, let alone specific to it. More crucially, you must pay attention to the "can" in the multiple choice answers, because there is no guarantee that anything will happen when you double-delete an object.
In fact, all four answers basically say the same thing.
The quiz seems confused anyway, since "deleting a pointer" is likely not what it means.
Not to be confused with SNMP traps:
In SNMP, a trap is a type of PDU used to report an alert or other asynchronous event about a managed subsystem.
Deleting the same memory which has been already deleted is undefined behavior. Anything could happen, although in my case, it gave a runtime error. Compiled in C++ using g++ 4.9.1
My program:
int main()
{
int x = 5;
int *ptr = &x;
delete ptr;
delete ptr;
}
It gave the following error:
*** Error in `./t': free(): invalid pointer: 0xbf971994 ***
I have a program which prompts me the error in VS2010, in debug :
Error: Stack around the variable 'x' was corrupted
This gives me the function where a stack overflow likely occurs, but I can't visually see where the problem is.
Is there a general way to debug this error with VS2010? Would it be possible to indentify which write operation is overwritting the incorrect stack memory?
thanks
Is there a general way to debug this error with VS2010?
No, there isn't. What you have done is to somehow invoke undefined behavior. The reason these behaviors are undefined is that the general case is very hard to detect/diagnose. Sometimes it is provably impossible to do so.
There are however, a somewhat smallish number of things that typically cause your problem:
Improper handling of memory:
Deleting something twice,
Using the wrong type of deletion (free for something allocated with new, etc.),
Accessing something after it's memory has been deleted.
Returning a pointer or reference to a local.
Reading or writing past the end of an array.
This can be caused by several issues, that are generally hard to see:
double deletes
delete a variable allocated with new[] or delete[] a variable allocated with new
delete something allocated with malloc
delete an automatic storage variable
returning a local by reference
If it's not immediately clear, I'd get my hands on a memory debugger (I can think of Rational Purify for windows).
This message can also be due to an array bounds violation. Make sure that your function (and every function it calls, especially member functions for stack-based objects) is obeying the bounds of any arrays that may be used.
Actually what you see is quite informative, you should check in near x variable location for any activity that might cause this error.
Below is how you can reproduce such exception:
int main() {
char buffer1[10];
char buffer2[20];
memset(buffer1, 0, sizeof(buffer1) + 1);
return 0;
}
will generate (VS2010):
Run-Time Check Failure #2 - Stack around the variable 'buffer1' was corrupted.
obviously memset has written 1 char more than it should. VS with option \GS allows to detect such buffer overflows (which you have enabled), for more on that read here: http://msdn.microsoft.com/en-us/library/Aa290051.
You can for example use debuger and step throught you code, each time watch at contents of your variable, how they change. You can also try luck with data breakpoints, you set breakpoint when some memory location changes and debugger stops at that moment,possibly showing you callstack where problem is located. But this actually might not work with \GS flag.
For detecting heap overflows you can use gflags tool.
I was puzzled by this error for hours, I know the possible causes, and they are already mentioned in the previous answers, but I don't allocate memory, don't access array elements, don't return pointers to local variables...
Then finally found the source of the problem:
*x++;
The intent was to increment the pointed value. But due to the precedence ++ comes first, moving the x pointer forward then * does nothing, then writing to *x will be corrupt the stack canary if the parameter comes from the stack, making VS complain.
Changing it to (*x)++ solves the problem.
Hope this helps.
Here is what I do in this situation:
Set a breakpoint at a location where you can see the (correct) value of the variable in question, but before the error happens. You will need the memory address of the variable whose stack is being corrupted. Sometimes I have to add a line of code in order for the debugger to give me the address easily (int *x = &y)
At this point you can set a memory breakpoint (Debug->New Breakpoint->New Data Breakpoint)
Hit Play and the debugger should stop when the memory is written to. Look up the stack (mine usually breaks in some assembly code) to see whats being called.
I usually follow the variable before the complaining variable which usually helps me get the problem. But this can sometime be very complex with no clue as you have seen it. You could enable Debug menu >> Exceptions and tick the 'Win32 exceptions" to catch all exceptions. This will still not catch this exceptions but it could catch something else which could indirectly point to the problem.
In my case it was caused by library I was using. It turnout the header file I was including in my project didn't quite match the actual header file in that library (by one line).
There is a different error which is also related:
0xC015000F: The activation context being deactivated is not the most
recently activated one.
When I got tired of getting the mysterious stack corrupted message on my computer with no debugging information, I tried my project on another computer and it was giving me the above message instead. With the new exception I was able to work my way out.
I encountered this when I made a pointer array of 13 items, then trying to set the 14th item. Changing the array to 14 items solved the problem. Hope this helps some people ^_^
One relatively common source of "Stack around the variable 'x' was corrupted" problem is wrong casting. It is sometimes hard to spot. Here is an example of a function where such problem occurs and the fix. In the function assignValue I want to assign some value to a variable. The variable is located at the memory address passed as argument to the function:
using namespace std;
template<typename T>
void assignValue(uint64_t address, T value)
{
int8_t* begin_object = reinterpret_cast<int8_t*>(std::addressof(value));
// wrongly casted to (int*), produces the error (sizeof(int) == 4)
//std::copy(begin_object, begin_object + sizeof(T), (int*)address);
// correct cast to (int8_t*), assignment byte by byte, (sizeof(int8_t) == 1)
std::copy(begin_object, begin_object + sizeof(T), (int8_t*)address);
}
int main()
{
int x = 1;
int x2 = 22;
assignValue<int>((uint64_t)&x, x2);
assert(x == x2);
}
I have a very simple C++ code here:
char *s = new char[100];
strcpy(s, "HELLO");
delete [] s;
int n = strlen(s);
If I run this code from Visual C++ 2008 by pressing F5 (Start Debugging,) this always result in crash (Access Violation.) However, starting this executable outside the IDE, or using the IDE's Ctrl+F5 (Start without Debugging) doesn't result in any crash. What could be the difference?
I also want to know if it's possible to stably reproduce the Access Violation crash caused from accessing deleted area? Is this kind of crash rare in real-life?
Accessing memory through a deleted pointer is undefined behavior. You can't expect any reliable/repeatable behavior.
Most likely it "works" in the one case because the string is still "sitting there" in the now available memory -= but you cannot rely on that. VS fills memory with debug values to help force crashes to help find these errors.
The difference is that a debugger, and debug libraries, and code built in "debug" mode, likes to break stuff that should break. Your code should break (because it accesses memory it no longer technically owns), so it breaks easier when compiled for debugging and run in the debugger.
In real life, you don't generally get such unsubtle notice. All that stuff that makes things break when they should in the debugger...that stuff's expensive. So it's not checked as strictly in release. You might be able 99 times out of 100 to get away with freeing some memory and accessing it right after, cause the runtime libs don't always hand the memory back to the OS right away. But that 100th time, either the memory's gone, or another thread owns it now and you're getting the length of a string that's no longer a string, but a 252462649-byte array of crap that runs headlong into unallocated (and thus non-existent, as far as you or the runtime should care) memory. And there's next to nothing to tell you what just happened.
So don't do that. Once you've deleted something, consider it dead and gone. Or you'll be wasting half your life tracking down heisenbugs.
Dereferencing a pointer after delete is undefined behavior - anything can happen, including but not limited to:
data corruption
access violation
no visible effects
exact results will depend on multiple factors most of which are out of your control. You'll be much better off not triggering undefined behavior in the first place.
Usually, there is no difference in allocated and freed memory from a process perspective. E.g the process only has one large memory map that grows on demand.
Access violation is caused by reading/writing memory that is not available, ususally not paged in to the process. Various run-time memory debugging utilities uses the paging mechanism to track invalid memory accesses without the severe run time penalty that software memory checking would have.
Anyway your example proves only that an error is sometimes detected when running the program in one environment, but not detected in another environment, but it is still an error and the behaviour of the code above is undefined.
The executable with debug symbols is able to detect some cases of access violations. The code to detect this is contained in the executable, but will not be triggered by default.
Here you'll find an explanation of how you can control behaviour outside of a debugger: http://msdn.microsoft.com/en-us/library/w500y392%28v=VS.80%29.aspx
I also want to know if it's possible
to stably reproduce the Access
Violation crash caused from accessing
deleted area?
Instead of plain delete you could consider using an inline function that also sets the value of the deleted pointer to 0/NULL. This will typically crash if you reference it. However, it won't complain if you delete it a second time.
Is this kind of crash rare in
real-life?
No, this kind of crash is probably behind the majority of the crashes you and I see in software.