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.
Related
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.
I am running into a problem in a very large coding project I'm doing. In one function I need to iterate through a map and insert some things but the way the program works is that the first couple times through the map isn't initialized yet and I cannot initialize it in that function because it is initialized else where where it needs to be. So the problem is the first couple of times through when I try to iterate through the map and it is not yet initialized the program crashes. I was googling and so forth looking for a way to test if map has been initialized before continuing with that section of the code. The way I verified the problem is by bypassing that segment of code for the first 5k cycles. This works for this particular benchmark but this isn't a robust method and I need something that will work for a lot of different benchmarks. Thanks in advance.
if(map_is_initialized>=5000)
{
for(std::map<RAddr, uint32_t>::iterator it = f_read_Prediction_Set->begin(); it != f_read_Prediction_Set->end(); ++it)
{
set = (((it->first) >> log2AddrLs) & maskSets) << log2Assoc;
if(set == caddr)
(*currentSets)[set] = 1;
}
}
map_is_initialized+=1;
I assume it's a map pointer,
If you've access to the class's constructor, Initialize it to NULL
If you don't have, try to initialize it to NULL in an early called function or subclass's constructor
Later on, you can check if it's not NULL
Your question is a little unclear. Depending on what is going on, you have options:
If it is as simple as some other code prior to that loop is building the map, you could:
Run the other code until the map is initialized before you enter the benchmark loop.
Either initialize the map pointer to NULL or use some "initialized" flag, and do not process the data if the pointer is NULL or the flag is not set.
If it is being done in a separate thread; a proper event / condition variable would do the trick, or whatever equivalent of while (!map_initialized) yield(); you have.
While writing a new vst-plugin using VSTGUI I'm really struggling with how to use the library, and most progress is made from guessing and debugging after (because there really is no documentation besides the million lines and ygrabit, which states little more than the obvious).
So far it's going good, but my last contribution to the project involved threads which made the design a little bit more problematic. Specifically, I'm working on a set of textlabels in a container (doing non-atomic operations) and these may (and obviously does) get destructed without my knowledge, when a user closes the window.
Even adding checks right before changing elements might still be a problem. So I actually need to control the lifetime of these objects (which is fine) except when they are shown in a CViewContainer, it automatically assumes ownership.
I have no idea how to write the backbone of the editor, so i used a program called VSTGUIBuilder for this, and appended (and basically rewrote) what i needed. However, since all 'views' you can work with requires either a parent or a systemwindow, you cannot instantiate any views/controls before reaching the AEffEditor::Open() function, which is called whenever your window is popped up.
And the AEffEditor::close() method is called whenever the window is closed. Now, the vstguibuilder put a
delete frame;
inside the AEffEditor::close() method which suggests you rebuild and dispense all resources on every open and close. Can this really be true? And if it is, is there no way i can protect my container's contents (which for details is a vector< CTextLabel *>) from getting deleted mid-function? It's no problem to dispose of it afterwards, I'm just worrying about segfaults while changing it.
Using mutexes and the such is really the last resort (if the call is coming from the host), I don't want to hang the host in any case if my code faults and never releases.
Edit:
I ended up finding a solution which is not so elegant, but works safely. Here's the code in the worker function:
while(bLock) {
Sleep(0);
}
bLock = true;
if(msgs.empty())
return;
/*
Prevent someone deletes our lines in close().
we create a copy of the container to be 100% sure
and increase the reference count, so we can safely
work with our own container and we 'forget' them
afterwards, so they will be deleted if needed.
This ensures that close AND open can be called
meanwhile we are working with the lines
*/
bDeleteLock = true;
// also the copy constructor should work as expected here
// since we are working with pointers, we still reference the same content.
auto copy_lines = lines;
for each(auto line in copy_lines) {
line->remember();
}
bDeleteLock = false;
...
for each(auto line in copy_lines) {
line->forget();
}
cont->setDirty();
bLock is another 'mutex' that protects a message queue, which this function will print out. bDeleteLock protects the process of copying the line container and 'remembering' them, and instantly releases if afterwards. Both are declared as volatile bools, shouldn't that be enough? Here's the close() method btw.
void CConsole::Close() {
// locking lines while copying them over in a container we can work with
while(bDeleteLock)
Sleep(0);
//waiting for bLock is not needed because it wont get deleted.
if(!visible) //if we are not visible it's our responsibility to remove the view
delete cont;
lines.clear();
}
Ahh, VSTGUI, that brings back some dark memories. ;) But seriously, yes, you will probably have to use a mutex to prevent the host from hanging. Having to instantiate everything when the window reopens seems kind of silly, but you can see many plugins do just that.
One potential workaround is to use a shared memory segment for cached view data, and then pass a reference to the location back to your plugin
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".
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.