I have a C++ program on Linux that crashes after some time with the message:
*** glibc detected *** free(): invalid pointer: 0x41e0ce94 ***
Inside the program I make extensive use of containers. They have to store objects of a simple class.
EDIT 2009-4-17:
In the meantime it seems clear that the error has nothing to do with the simple class. The error still occurs if I change the containers to hold other datatypes. The problem must be somewhere else in my code, I'm trying to figure it out at the moment...
Consider using a std::string to hold the string value instead of a raw char pointer. Then you won't have to worry about managing the string data in your assignment, copy, and destruction methods. Most likely your problem lies there.
Edit: There's no issue with the newer class you posted, and no problem with the first version if you're only using the char * to point to string constants. The problem lies elsewhere in the program or with the way you're using the class. You'll have to spend more time digging in the debugger and/or valgrind to track down the problem. I would figure out what is pointed to at the specified address and try determine why it's being freed twice.
At a guess, there is something wrong in your copy ctor, assignment op or destructor - you need to show the code for those.
Edit: Just noticed you don't have an assignment operator - assuming your copy constructor & destructor are OK, you need an assignment operator too, as the std:; containers will use it.
I have been fighting with a C/C++ application we are developing, and the first ideas that come to my mind are
A pointer has been modified and its pointing to an invalid possition (ptr++;) or something like that.
You have freed the object, but the pointer still holds the direction.
A tool like Valgrind may help you to detect possible errors in the code. To install:
sudo apt-get install valgrind
And to use it:
valgrind --tool=memcheck --leak-check=full ...
It will report errors while the program is running, and it will give you also a report after the program ends. The only problem is what valgrind identifies as a possible problem may not be a real problem. But it is an starting point.
It's most certainly a bad string value. Using std::string maybe help in this regard if it is a dangling pointer issue. Also ensure all the string initializations work as expected.
If I understand the class correctly, you assume that whatever memory resides at m_cstring won't be deallocated for the lifetime of the class. Which in your case also means for the lifetime of the containers. Check your scopes.
Another problem you may be encountering is if your Destructor is deleting the cstring then using a default value in the constructor is a really bad idea as you will be trying to deallocate a statically allocated cstring.
It is possible in C++ to define a function that is supposed to return a string, but doesn't return anything and you wind up with a bad string (Typically the compiler will catch the 'Reached end of non-void function', but not always).
Ditto on using valgrind.
As an addendum after reading various comments, there's always the possibility that a memory error somewhere else in the program corrupted one of the strings.
EDIT 4-16
At this point I would verify the values of the object are well formed on construct/destruct. (try printing them?) If everything looks good, you may have to look elsewhere in your code for the error.
What is inside your destructor? Probably it does free of the cstring. And If it is the case then you share your cstring pointer over instances and each instance then frees the same pointer.
Related
I've adapted Matt Gallagher's "Testing if an arbitrary pointer is a valid object pointer" in an iOS project which uses Objective-C++. It's working fine with Objective-C objects but it always tells me that my C++-Pointers are invalid regardless of whether it works or not. Sometimes the Code crashes at the pointer. Sometimes the code works fine. But the test-method always tells me the pointer is wrong.
Is here anybody who knows to adapt this code to C++ classes and objects too? I could imagine that the code is only working with Objective-C according to the use of "Class"
The contents of a pointer variable is either: A null pointer, a valid pointer to an object, a valid pointer to an array element or past the last element of an array, or some invalid pointer.
If it is an invalid pointer, then any attempt to use it invokes undefined behaviour. That includes any attempt to check that it is an invalid pointer. And there you are stuck. All you can do is check whether it is a null pointer, or whether it is equal to some other valid pointer.
You should go with the Objective-C philosophy: Trying to use an invalid pointer is a programming error. You don't try to detect and handle this at runtime. You let it crash and fix the bug in your code.
C++ pointers simply reference an address in memory. You could look at what's there in memory using a memory viewer tool, but that wouldn't even guarantee that the memory is still valid. For example:
char* test = new[13];
strcpy(test, "Hello World!");
delete[] test;
.
.
.
printf("%s", test);
In some cases this will print successfully. Sometimes it will print a garbage string. And sometimes it will segfault. There is nothing there to speak to the pointer's validity.
If you're looking at a program that has just segfaulted and you're trying to see what happened there are a few options available to you:
You can look at the memory through a memory viewer, that in combination with the line you faulted on can provide insight.
You can seed your memory before running to make this clearer use 0xbadfood5 or something similar.
Use Valgrind when running is a great tool, if you can deal with the overhead.
The best option is to do error checking in your code. It sounds like you don't have that or you wouldn't be here. Preconditions and postconditions are great and will save you a ton of time in the long run (like now.) However as a silver lining you should exploit this to exact better coding standards in your organization for the future.
I've got a large Mac app that runs for a couple of days at a time operating on a large data set. It's a mix of Objective-C++ and C++. It runs great on Mountain Lion, but on Mavericks, after running for about 10 to 20 minutes (in which a couple of million objects are allocated and destroyed), it crashes. It behaves as if it's crashing with an invalid pointer (i.e. calling a function on a deleted C++ object), but the object it's pointing to is in a state that makes absolutely no sense.
All my C++ classes inherit from a common base class where the constructor looks something like this:
MyClass::MyClass()
{
mCreated = 12345; //int member variable set here and NEVER TOUCHED AGAIN.
//other initialization stuff
}
When it crashes, the debugger shows that in the bad object, the value for mCreated is 0. It's behaving as if the object never ran its constructor!
I don't think it's memory stomping, because this value is never anything other than 0 or its expected value, and none of the other fields in the object have values that look like the garbage you'd expect from memory stomping.
I've also tried running with scribble turned on, and the 0x555 and 0xaaa values don't show up anywhere. I've also tried Guard Edges.
In-depth investigation has not revealed anything. The bad object isn't even always the same class. All I can think of is that something with the new memory stuff in Mavericks (compressing unused memory) is causing some new behavior (maybe a bug or maybe some previously unknown, mostly-unenforced rule that now really matters).
Has anyone seen anything similar? Or does anyone know of any mostly-unknown memory rules that would apply more strongly under Mavericks?
I think you're right about the invalid pointer suspicion. It might be a pointer to a deleted object or it might be a garbage pointer. Either one would be consistent with the mCreated member being different than you expect. In the case of a deleted object, the memory could be used for something else and therefore set to some other value. In the case of a garbage pointer, you're not pointing to anything that ever was an instance of your class.
I don't know how well the Allocations instrument works for C++ objects, but you could try reproducing the crash under that. When it stops in the debugger, get the this pointer and then get the history of that address from Instruments.
If Instruments doesn't work, you can set the MallocStackLoggingNoCompact environment variable. Then, when it stops in the debugger, examine the this pointer and use the following commands to view the history of that address:
(lldb) script import lldb.macosx.heap
(lldb) malloc_info --stack-history 0x10010d680
(Use the this address instead of 0x10010d680, of course.)
Alternatively, you can use the malloc_history command from a shell to investigate the history, if doing it within LLDB is cumbersome.
I have some code I wrote a few years ago. It has been working fine, but after a recent rebuild with some new, unrelated code elsewhere, it is no longer working. This is the code:
//myobject.h
...
inline CMapStringToOb* GetMap(void) {return (m_lpcMap);};
...
The above is accessed from the main app like so:
//otherclass.cpp
...
CMapStringToOb* lpcMap = static_cast<CMyObject*>(m_lpcBaseClass)->GetMap();
...
Like I said, this WAS working for a long time, but it's just decided to start failing as of our most recent build. I have debugged into this, and I am able to see that, in the code where the pointer is set, it is correctly setting the memory address to an actual value. I have even been able to step into the set function, write down the memory address, then move to this function, let it get 0xfdfdfdfd, and then manually get the memory address in the debugger. This causes the code to work. Now, from what I've read, 0xfdfdfdfd means guarding bytes or "no man's land", but I don't really understand what the implications of that are. Supposedly it also means an off by one error, but I don't understand how that could happen, if the code was working before.
I'm assuming from the Hungarian notation that you're using Visual Studio. Since you do know the address that holds the map pointer, start your program in the debugger and set a data breakpoint when that map pointer changes (the memory holding the map pointer, not the map pointed to). Then you'll find out exactly when it's getting overwritten.
0xfdfdfdfd typically implies that you have accessed memory that you weren't supposed to.
There is a good chance the memory was allocated and subsequently freed. So you're using freed memory.
static_cast can modify a pointer and you have an explicit cast to CMyObject and an implicit cast to CMapStringToOb. Check the validity of the pointer directly returned from GetMap().
Scenarios where "magic" happens almost always come back to memory corruption. I suspect that somewhere else in your code you've modified memory incorrectly, and it's resulting in this peculiar behavior. Try testing some different ways of entering this part of the code. Is the behavior consistent?
This could also be caused by an incorrectly built binary. Try cleaning and rebuilding your project.
I have a relatively large class that I'm working with and it's all worked fine so far (note: I didn't actually write the class, I'm just adding some functionality). However, after declaring one more string in the header file, everything now crashes (I get a memory access error). If I erase that string and rebuild, everything works fine.
I'm not actually doing ANYTHING with that string....just the act of declaring it is causing some weird memory error.
I can't explain in much more detail than this, since it would be a waste to try to explain every function. What kind of things should I look for here to find the problem? What might cause this weird behavior?
The error itself is:
Unhandled exception at 0x65fd17fd (msvcp80d.dll) in myFile.exe: 0xC0000005: Access violation writing location 0xcdcdcdcd.
Basically all that changed in the .h file was:
StringType string1;
Turned into:
StringType string1;
StringType string2;
StringType is an extension of basic_string
You've allocated some memory on the heap and failed to initialize it.
0xcd is a fill pattern used by the debug heap: before dynamically allocated memory is given to your program, it is filled with that pattern to help you find uninitialized variables.
As for why changing the class definition affects the outcome, you may be doing incorrect pointer arithmetic, accessing something beyond the end of a dynamically allocated object, or one of any number of other things that no longer manifests as a bug when you have a larger object. You could also be violating the one-definition rule if some of the source was built using the old definition and some of the source is built with the new definition.
There are many things that can cause this kind of problem: your best bet is to break in the debugger when it happens, and trace backwards to see where the error originated (sometimes this can be lots of fun; I had to trace an uninitialized variable across a network connection once).
I've got a strange problem here. Assume that I have a class with some virtual methods. Under a certain circumstances an instance of this class should call one of those methods. Most of the time no problems occur on that stage, but sometimes it turns out that virtual method cannot be called, because the pointer to that method is NULL (as shown in VS), so memory access violation exception occurs. How could that happen?
Application is pretty large and complicated, so I don't really know what low-level steps lead to this situation. Posting raw code wouldn't be useful.
UPD: Ok, I see that my presentation of the problem is rather indefinite, so schematically code looks like
void MyClass::FirstMethod() const { /* Do stuff */ }
void MyClass::SecondMethod() const
{
// This is where exception occurs,
// description of this method during runtime in VS looks like 0x000000
FirstMethod();
}
No constructors or destructors involved.
Heap corruption is a likely candidate. The v-table pointer in the object is vulnerable, it is usually the first field in the object. A buffer overflow for some kind of other object that happens to be adjacent to the object will wipe the v-table pointer. The call to a virtual method, often much later, will blow.
Another classic case is having a bad "this" pointer, usually NULL or a low value. That happens when the object reference on which you call the method is bad. The method will run as usual but blow up as soon as it tries to access a class member. Again, heap corruption or using a pointer that was deleted will cause this. Good luck debugging this; it is never easy.
Possibly you're calling the function (directly or indirectly) from a constructor of a base class which itself doesn't have that function.
Possibly there's a broken cast somewhere (such as a reinterpret_cast of a pointer when there's multiple inheritance involved) and you're looking at the vtable for the wrong class.
Possibly (but unlikely) you have somehow trashed the vtable.
Is the pointer to the function null just for this object, or for all other objects of the same type? If the former, then the vtable pointer is broken, and you're looking in the wrong place. If the latter, then the vtable itself is broken.
One scenario this could happen in is if you tried to call a pure virtual method in a destructor or constructor. At this point the virtual table pointer for the method may not be initialized causing a crash.
Is it possible the "this" pointer is getting deleted during SecondMethod's processing?
Another possibility is that SecondMethod is actually being called with an invalid pointer right up front, and that it just happens to work (by undefined behavior) up to the nested function call which then fails. If you're able to add print code, check to see if "this" and/or other pointers being used is something like 0xcdcdcdcd or 0xfdfdfdfd at various points during execution of those methods. Those values are (I believe) used by VS on memory alloc/dealloc, which may be why it works when compiled in debug mode.
What you are most likely seeing is a side-effect of the actual problem. Most likely heap or memory corruption, or referencing a previously freed object or null pointer.
If you can consistently have it crash at the same place and can figure out where the null pointer is being loaded from then I suggest using the debugger and put a breakpoint on 'write' at that memory location, once the breakpoint is trigerred then most likely you are viewing the code that has actually caused the corruption.
If memory access violation happens only when Studio fails to show method address, then it could be caused by missing debug information. You probably are debugging the code compiled with release (non-debug) compiler/linker flags.
Try to enable some debug info in C++ properties of project, rebuild and restart debugger. If it will help, you will see all normal traceable things like stack, variables etc.
If your this pointer is NULL, corruption is unlikely. Unless you're zeroing memory you shouldn't have.
You didn't say if you're debugging Debug (not optimized) or Release (optimized) build. Typically, in Release build optimizer will remove this pointer if it is not needed. So, if you're debugging optimized build, seeing this pointer as 0 doesn't mean anything. You have to rely on the deassembly to tell you what's going on. Try turning off optimization in your Release build if you cannot reproduce the problem in Debug build. When debugging optimized build, you're debugging assembly not C++.
If you're already debugging a non-optimized build, make sure you have a clean rebuild before spending too much time debugging corrupted images. Debug builds are typically linked incrementally and incremental linker are known to produce problems like this. If you're running Debug build with clean build and still couldn't figure out what went wrong, post the stack dump and more code. I'm sure we can help you figure it out.