Getting a SEGFAULT from a referenced Vector [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
The Issue:
So, I've been banging my head against the wall on this one. I have an application that compiles and runs fine on OSX and Linux, but when I compile it on Windows with MingW64, I get a SEGFAULT during run time. So here's what happens;
I have a Map Class which contains std::vector<Tilesheet*> m_tilesheets. I pass this Variable off into another class, MapLayer, by reference to the constructor:
MapLayer::MapLayer(std::vector<unsigned int>& p_data,
std::vector<MindTrip::Graphics::TileSheet*>& p_tilesheets)
: m_data(p_data),
m_tilesheets(p_tilesheets)
{
DrawTexture();
}
The vector gets stored as a reference in the MapLayerClass, std::vector<MindTrip::Graphics::TileSheet*>& m_tilesheets;
If I put a breakpoint on the first line of that constructor, m_tilesheets has a defined value for _M_First. If I put a break point at the last line of the constructor, m_tilesheets no longer has a defined value for _M_First. I am doing no multithreading, and the application has not yet left the scope these variables were defined.
In its next function called DrawTexture(), there is a foreach loop iterating through m_tilesheets which keeps giving me a SEGFAULT:
void MapLayer::DrawTexture() {
for(unsigned int tile_val: m_data)
{
// SEGFAULT ON THIS LINE
for(MindTrip::Graphics::TileSheet* tileSheet : m_tilesheets)
{
}
}
}`
Here is what I've tried:
I have tried converting this to a regular for loop, but still get the same issue.
I have tried using references to grab objects from the vector by turning the foreach loop into this:
for(auto& tileSheet : m_tilesheets). Same Problem
If I move m_tilesheets out of the MapLayer class & its constructor and pass it as a argument instead to DrawTexture as a reference:
MapLayer::DrawTexture(std::vector<MindTrip::Graphics::TileSheet*>& p_tilesheets)
M_data starts throwing a segfault instead in its foreach loop. Which is weird because m_data's foreach loop actually happens on the line before m_tilesheet's: for(unsigned int tile_val: m_data)
So, in response to that issue I tried moving m_data to an argument of DrawTexture and remove it as a member, just like I did for m_tilesheets, passed by reference:
MapLayer::DrawTexture(std::vector<MindTrip::Graphics::TileSheet*>& p_tilesheets, std::vector<unsigned int>& p_data)
At the time I tried this, I was using a for loop instead of a foreach. There should have been 1 entry in p_tilesheets and 10000 entries in p_data. This time the segfault threw at the line I was accessing p_tilsheet's data with p_tilesheet[j]; j was not out of range and was set to 0.
After trying all this, I reset my code back to what it was, and instead decided maybe I will use std::copy() to copy the data in the vector, and instead of using references in the class, I just instantiated new variables for m_tilesheets and m_data. I switched the foreach back to a regular for loop and again, was getting segfaults accessing the element [j] of m_tilesheets.
I'm so baffled as to what is even going on with my memory. m_tilesheets and m_data are not null when they're being accessed, and their _M_First property gets unset somehow even before the end of the constructor.
Again, only happens on windows. OSX and Linux work fine. The application was running fine on windows before I implemented the map class. Not just looking for the fix as an answer, but the reason the bug is occuring.
Edit:
Here is the constructor to Map, where I am defining these values and passing them off to new instances of MapLayer.
Map::Map(const char* p_map_file)
{
m_tile_sheets.push_back(new MindTrip::Graphics::TileSheet("PathToTilesheet", 0));
std::vector<unsigned int> data(10000, 50);
m_layers.push_back(new MapLayer(data, m_tile_sheets));
}

Your problem is not occurring in the code you provided. This code is just triggering the bug. Also (as others also pointed out), your code is not working correctly on Linux & OSX, it's just not exhibiting the bug.
Since you are compiling on Linux as well, I'd suggest you to run your code through valgrind, and scan output for uninitialized variables, buffer overruns, etc...
To start it you might use the following:
valgrind --tool=memcheck --track-origins=yes --log-file=log.txt your_prog arg arg
after finished tun you will have (huge) amount of data to check contained within log.txt. Your problem will almost certainly be shown.
Other than that, I'd ask you why are you using raw pointers? If you don't have very good reason for this, I would suggest to use something else (smart pointers for TileSheets/MapLayers, and std::string instead of char*, for example). Naked pointers are "the quickest way" to create this kind of bugs.

Related

std::list iterator strange behavior

for 2 days now, I have been trying to find out where is the problem in my code. I have isolated the problem like this:
There is loop which look like this:
int test_counter = 0; //Debug purpose only
for (const_iterator i = begin(); i != end(); i++, test_counter++){
if ((*i)->isSoloed()) {
soloed = (*i);
break;
}
}
It is in one method of the class that inherits std::list. The list contains pointers to some dynamically allocated instances of some class, but that is likely not important here.
The list contains exactly two pointers.
The problem is that in about 20% runs, the second pass (test_counter == 1) crashes on (*i)->isSoloed() with access violation. In this case, the iterator value is 0xfeeefeee. This exact value is used by VisualStudio to indicate that the memory has been freed. Well that doesn't make any sense from at least 3 reasons:
No memory gets dealocated here or in another threads
Even if so, how would the iterator get that value???
If in the case of
crash (the exception window) I click break and look at the second
items in the list looks intact and everything seems OK.
Note that this is a multithreaded code which is likely to be the problem here, but the loop is read-only (I even used the const_iterator) and the other thread that has the pointer to this list does not write in the time when the loop is running. But even so, how could that affect the value of the iterator which is a local variable here!
Thanks a lot.
//edit:
I have also noticed 2 more interesting things:
1) if I break the debugging after the access violation occurs, I can go back (by dragging the next commant to execute arrow) before the loop and run it again without any problem. So the problem is unfortunatelly pretty undeterministic.
2) I have never been able to reproduce the problem in release build.
The signature of the method:
MidiMessageSequence::MidiEventHolder* getNextActiveEvent();
and it is called like this:
currentEvent = workingTrackList->getNextActiveEvent();
nothing special really. The application uses JUCE library, but that shouldn't be a problem. I can post more code, just tell me what should I post.
Two possible reasons.
1: The memory that i pointed to is deleted before it is accessed (*i). Try to add a check if(i) before access i (*i)->isSoloed().
2: Try to add a lock before you access the list or list item each time.
I haven't found out where exactly was the problem but I canceled the inheritance and agregated the std::list instead. With this the TrackList class became just a sort of wrapper around the std::list. I put a scoped lock in every method that accesses the list (in the wrapper, so from outside it works the same and I do not need to care about locking from outside) and this pretty much solved the problem.

General way of solving Error: Stack around the variable 'x' was corrupted

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);
}

Access violation in call to non-virtual member function

I have some piece of code that runs many times and suddenly reports an access violation.
for(std::list<Projectile>::iterator it = projectiles.begin(); it != projectiles.end();) {
bool finished = ...
// try to print address of collides(), prints always 1
std::cout << &Projectile::collides << std::endl;
// here it crashes:
if(it->collides(&hero)) {
std::cout << "Projectile hits " << hero.getName() << std::endl;
finished = it->apply(&hero);
}
// ...
if(finished) {
it = projectiles.erase(it);
} else {
++it;
}
}
So VS debug stacktrace says that in line if(it->collides(&hero)) { the program tries to call a method at cdcdcdcd() which causes the access violation.
it, *it and hero are valid objects according to VS.
So I assume that cdcdcdcd() should actually be collides(). Since collides is a non-virtual method its address should basically not change or?
The thing is that the method collides() is executed several times before successfully, but suddenly it does not work anymore.
Can it be that the address is changed? Have I overwritten it?
Please help me! Also I appreciate information on anything that is not fine with this code :)
0xcdcdcdcd is a fill pattern used by the Win32 Debug CRT Heap; assuming you're running in a debugger on Windows, this may be a significant clue. There's a decent explanation of the heap fill patterns here.
My guess is you're somehow either invalidating the iterator elsewhere, or have some other buffer overflow or dangling pointer or other issue.
Application Verifier may help with diagnosing this. You may also want to look into the other things mentioned in the question How to debug heap corruption errors? or some of the techniques from Any reason to overload global new and delete? (disclaimer: at the moment I have the top-rated answer on both).
If your STL library has a debugging feature it may help ferret this out as well. Metrowerks (now Freescale) Codewarrior has the define _MSL_DEBUG, for example, that can be used to build a version of the standard libraries (including std::list) which will detect common issues like iterator invalidation (at some runtime cost).
It looks like Visual Studio has debug iterator support which might fit the bill, if you're using that.
Your termination condition seems wrong [EDIT: actually it looks correct, even if it still scares me. See comments.]. When finished becomes true, you erase the current projectile and then set the iterator to ... something. There is no reason to think that the loop will terminate at this point. It's is likely that it will eventually either start pointing outside of the list, or to an otherwise invalid object (which your debugger will not always flag as such).
When you erase the projectile, you should just explicitly leave the loop using "break".

Seg fault on C++ map access

I've come across a strange issue in some code that I'm working on. Basically what's going on is that whenever I try to get some information from an empty map, the program segfaults. Here's the relevant code:
(note that struct Pair is a data structure that is defined earlier, and sendMasks is a std::map that is good)
std::map<std::string*, struct Pair*>::iterator it;
for(it = sendMasks->begin(); it != sendMasks->end(); it++){ //segfault
//(some code goes here)
}
I know that the pointer to the map is good; I can do
it = sendMasks->begin();
it = sendMasks->end();
before my loop, and it doesn't segfault at all then.
Now, if I put the following test before the for loop, it will segfault:
if( sendMasks->empty() )
As will any other attempt to determine if the map is empty.
This issue will only occur if the map is empty. My only thought on this issue would be that because I am updating sendMasks in a separate thread, that it may not have been updated properly; that however doesn't make any sense because this will only happen if the map is empty, and this code has worked perfectly fine before now. Any other thoughts on what could be happening?
EDIT:
I figured out what the problem was.
At an earlier part in my code, I was making a new char* array and putting that pointer into another array of length 4. I was then putting a NULL character at the end of my new array, but accidentally only did a subscript off of the first array - which went off the end of the array and overwrote a pointer. Somehow, this managed to work properly occasionally. (valgrind doesn't detect this problem)
The sequence was something like this:
object* = NULL; //(overwritten memory)
object->method();
//Inside object::method() :
map->size(); //segfault. Gets an offset of 0x24 into the object,
//which is NULL to begin with. memory location 0x24 = invalid
I wasn't expecting the instance of the object itself to be null, because in Java this method call would fail before it even did that, and in C this would be done quite differently(I don't do much object-oriented programming in C++)
If you are accessing a data structure from different threads, you must have some kind of synchronization. You should ensure that your object is not accessed simultaneously from different threads. As well, you should ensure that the changes done by one of the threads are fully visible to other threads.
A mutex (or critical section if on Windows) should do the trick: the structure should be locked for each access. This ensures the exclusive access to the data structure and makes the needed memory barriers for you.
Welcome to the multithreaded world!
Either:
You made a mistake somewhere, and have corrupted your memory. Run your application through valgrind to find out where.
You are not using locks around access to objects that you share between threads. You absolutely must do this.
I know that the pointer to the map is good; I can do
it = sendMasks->begin();
it = sendMasks->end();
before my loop, and it doesn't segfault at all then.
This logic is flawed.
Segmentation faults aren't some consistent, reliable indicator of an error. They are just one possible symptom of a completely unpredictable system, that comes into being when you have invoked Undefined Behaviour.
this code has worked perfectly fine before now
The same applies here. It may have been silently "working" for years, quietly overwriting bytes in memory that it may or may not have had safe access to.
This issue will only occur if the map is empty.
You just got lucky that, when the map is empty, your bug is evident. Pure chance.

What could cause a returning function to crash? C++

So I have been debugging this error for hours now. I writing a program using Ogre3d relevant only because it doesn't load symbols so it doesn't let me stack trace which made finding the location of the crash even harder. So, write before I call a specific function I print out "Starting" then I call the function and immediately after I print "Stopping". Throughout the function I print out letters A-F where F is printed right before the function returns (one line above the last '}') The weird thing is when the crash occurs it is after the 'F' is printed but there is no 'Stopping'. Does this mean that the crash is happening in between somewhere? The only thing I can think of is something going wrong during the deallocation of some of the memory allocated during the function. I've never had anything happen like this, I will keep checking to make sure it's going wrong where I think it is.
Most of the times when something weird and un-understandable happens, it's because of something else.
You could have some dangling pointers in your code (even in a place far away from that function) pointing to some random memory cells.
You might have used such dangling pointer, and it might have resulted in overwriting some memory cells you need. The result of this is that you changed the behavior of your program by changing some variable defined elsewhere, some constants, or even some code!
I'd suggest you to debug your application using some tool able to check and report erroneous memory accesses, like Valgrind.
Anyway if you are able to localize the source of your crash and to write a really small piece of code that will crash post it here -- it could be just a simple error in your function, although it sounds unlikely, from your description.
This probably means that the error is happening when the function returns and some destructor is firing. Chances are that you have some destructor trying to free memory it doesn't own, or writing off the end of some buffer in a log, etc.
Another possibility to be aware of might come up if you aren't flushing the output stream. It's possible that "Stopping" is getting printed, but is being buffered before hitting stdout. Make sure to check for this, since if that's what's going on you'll be barking up the wrong tree.
I had a similar problem, and it turned out that my function was not returning anything when the signature expected a return type of std::shared_ptr, even though I was not using the return anywhere.
The function had the following signature:
std::shared_ptr<blDataNode> blConditionBasedDataSelectionUI::selectData(std::shared_ptr<blDataNode> inputData)
{
// My error was due to the function
// not returning anything
}
I encountered the same problem and it turned out I forgot to init my vector before appending new items, which cause error when my function was comparing the vector with other list.
std::vector<cv::Point> lefteyeCV;
void Init() {
// I need to add "lefteyeCV.clear();" here!
for (int i = 0; i < 8; i++) {
lefteyeCV.push_back(cv::Point(0, 0));
}
}
// the following comparison will crash after "return 0"
// because cl_ is of size 8, but if I run "Init()" twice, lefteyeCV.size() = 16
// then the comparison is out of range.
int irisTrack(){
for (int i = 0; i < lefteyeCV.size(); i++) {
cl_[i] = cv::Point(lefteyeCV[order[i]].x - leftRect.x, lefteyeCV[order[i]].y - leftRect.y);
}
return 0;
}
What's confusing is that, I'm using Xcode and the app crash right after "return 0" with the indecipherable message "thread 13: signal SIGABRT". However, using Visual Studio instead showed me the line where index is out of range.