SEGFAULT Occuring Outside GDB, but not inside.

This topic is 2461 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

We've all had it happen at some point. Our program runs just fine until somewhere along the line it crashes. So we think, ok, I know why it happened, let's get some data with my trusty debugger and... what... why is it not happening?! WAT!?

Need some advice on how to figure out where this little asshole of an error is occurring. I can reproduce the crash reliably, but I am at a loss as to where it is actually occurring because GDB magically fixes it. It could be happening in any number of places (collision detection, update routine, etc...)

Share on other sites
Are you initializing all of your variables? Sometimes that causes problems like this.

Share on other sites

Are you initializing all of your variables? Sometimes that causes problems like this.

+1 That's almost guaranteed to be the problem, gdb initializes everything to zero, so common constructs like [font="Courier New"]if(ptr != 0)[/font] will "remove" the error (it also won't crash deleting a non-existent object since [font="Courier New"]delete 0[/font] is well-defined as no-op).

Share on other sites
And it very well may have been that. I started compiling with -Wall and finally got some meaningful output out of GDB.

Now here's my new problem. For the life of me, I can't fathom why this is causing me problems...

void ObjectManager::PropagateTick(float delta) { Actor* o = NULL; int event = Events::ON_TICK; ObjectList::iterator i=m_ListeningActors[event].begin(); while( i != m_ListeningActors[event].end() ) { o = (*i); // It compplains about o->IsFlaggedForDeletion(), saying o==0xfeeeefeeee if( o == NULL || o->IsFlaggedForDeletion() ) { //Log::Beg(Log::INFO)<<"Found a null pointer during OnTick callback. Removing."<<Log::End(); i = m_ListeningActors[event].erase( i ); } else if( o->IsEnabled() ) { o->Update(delta); o->ReceiveTickEvent(delta); ++i; } else ++i; } }

m_ListeningActors is a boost::unordered_map<int,ObjectList>, and ObjectList is a typedef for std::vector<Actor*>

Share on other sites
At least in Windows 0xfeeeefeeee is a special value which gets stored into memory after you free it (which only happens when your program is started via a debugger).

It suggests that you are keeping a pointer around to something that was deleted earlier on.

Share on other sites
You are iterating over a list. When you get into the block of code that calls "erase(i)", I do not believe your iterator is valid after the erase(i) call. When you erase, if you are then finished with the list, just break from the loop. If there are multiple occurrences, consider building a new list from the old one, keeping only those things not erase()-d.

Share on other sites
The erase part is correct, he uses the iterator returned by it. Check if you don't put an Actor in several ObjectLists (ie. it subscribed to several events), as you seem to only remove the actor from the current ObectList. In those cases you'd have invalid pointers in the other lists.

Share on other sites
Yeah that is my biggest problem currently. My solution for now is to sort out actors by what events they subscribe to so that I am not iterating one giant list when I need to send events. However, I want to avoid using a set for this purpose since a test program I ran showed that iterating a set can be much slower than iterating a list, and searching for a single actor can be slower than that in the worst case. Then again, I could be doing it wrong in my test program, or horribly overthinking it.

• 10
• 18
• 14
• 18
• 15