SEGFAULT Occuring Outside GDB, but not inside.

Started by
6 comments, last by _orm_ 12 years, 7 months ago
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...)

Advertisement
Are you initializing all of your variables? Sometimes that causes problems like this.
Try attaching the debugger after starting the program.

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).
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*>
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.
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.
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.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

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.

This topic is closed to new replies.

Advertisement