C++ Program Crashing on Exit (Windows XP)

Started by
8 comments, last by Mr Awesome 17 years, 11 months ago
Right before my program exits, it crashes and windows gives me a message saying it encountered an error, asking me if I want to send an error report to Microsoft. Does anyone know of common reasons why this would happen?
Advertisement
Improper coding is normally the main cause.

Mind putting some code so we can see what your code is doing?

Beginner in Game Development?  Read here. And read here.

 

Well, it's kind of a large project, and the problem only occurs when I do a specific series of actions that involve adding and removing lists of boost::shared_ptrs to a main list. The strange thing is, it only happens when I use a certain type of boost::shared_ptr list, and only when it is the third thing added and the first thing removed.
Well if you're not going to post the code you'll likely have to solve it yourself. You can grab the logger code from Fluid Studios or make your own and start tracking this issue down. Also Visual Studios comes with a kick butt debugger, fire it up and get at it :-).

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

I'm using GDB from CodeBlocks, but it either isn't working or I don't understand how to use it. Here is the code for my GameManager class, there's quite a bit however:

// GameManager.h#include <iostream>#include <string>#include <list>#include <boost/shared_ptr.hpp>#include "GameEngine.h"#include "Misc/Singleton.h"#include "Misc/Colors.h"#include "2D/Camera2D.h"#include "2D/Wall2D.h"#include "Path.h"#include "ComponentListBase.h"#include "ComponentList.h"#include "TrackSegment.h"#include "StartPosition.h"#define Game GameManager::Instance()using std::string;using std::list;// File extensionsconst string COURSE_EXT = ".crs";  // Used in game.const string EDIT_EXT   = ".ecf";  // Editable course file for editor.// TODO: Search and change wall comments.// TODO: Make getting mouse state a little easier through GameEngine or utils.// Singleton that controls all data and functions of the game, including input,// updating data, and rendering.class GameManager : public GameEngine, public Singleton<GameManager>{    public:        typedef ComponentList<TrackSegment>          Track;        typedef ComponentList<Vector2D>              VertexList;        typedef ComponentList<StartPosition>         StartList;        typedef boost::shared_ptr<ComponentListBase> SectPtr;        typedef list<SectPtr>                        SectionList;        typedef SectionList::iterator                SectItr;        typedef SectionList::const_iterator          SectConstItr;        typedef SectionList::reverse_iterator        SectRItr;        typedef SectionList::const_reverse_iterator  SectConstRItr;        GameManager() {}        virtual ~GameManager() {}        void NewCourse(string filename, int width, int height);        void OpenEditable(string filename);        void SaveEditable(string filename);        void SaveCourse(string filename);        void ToggleLooped();        void ToggleDirection();        void ShowComponents(bool show);        void ShowConnections(bool show);        ModeType Mode() const { return m_Mode; }        void Mode(ModeType mode) { m_Mode = mode; DeselectSection(); }        void PointSize(double size)  { m_PointSize = size; }        void LineSize(double size)   { m_LineSize = size; }        void NormalSize(double size) { ResizeNormals(size / m_Camera.Scale() ); }        int WorldWidth() const   { return m_WorldWidth; }        int WorldHeight() const  { return m_WorldHeight; }        int WorkWidth() const    { return m_WorkWidth; }        int WorkHeight() const   { return m_WorkHeight; }    private:        virtual void GameInitialize();        virtual void Update(int elapsedTicks);        virtual void Render();        void         RenderSelectionBox();        virtual void KeyDown(int key, int mod);        virtual void KeyUp(int key, int mod);        virtual void MouseMotion(int button,                                 int x,    int y,                                 int relX, int relY );        virtual void MouseButtonDown(int button,                                     int x,    int y,                                     int relX, int relY );        virtual void MouseButtonUp(int button,                                   int x,    int y,                                   int relX, int relY );        virtual void WindowActive();        virtual void WindowInactive();        virtual void End();        void SelectSection(SectItr selection);        void DeselectSection();        void RemoveSection();        void ResizeNormals(double size);        /// GAME DATA        // Size of course.        int m_WorldWidth;        int m_WorldHeight;        // Area excluding toolbars, etc.        int m_WorkWidth;        int m_WorkHeight;        Camera2D m_Camera;        SectionList        m_Sections;        // Selected section.  Null if none are selected.        SectItr            m_SelectedSection;        // Holds copied parts of component lists.        SectPtr            m_Clipboard;        // Determines what type of vertex list to create.        ModeType           m_Mode;        // Used to keep track of selection rectangles.        Vector2D           m_ClickPos;        double             m_PointSize;        double             m_LineSize;        double             m_NormalSize;};// GameManager.cpp#include <iostream>#include <fstream>#include <string>#include <sstream>#include <list>#include <boost/shared_ptr.hpp>#include "SDL.h"#include <Gl/gl.h>#include "GameManager.h"#include "GuiManager.h"#include "Misc/Singleton.h"#include "Debug/Exception.h"#include "Misc/Utils.h"#include "Misc/Colors.h"#include "2D/Vector2D.h"#include "2D/Rectangle.h"#include "2D/Camera2D.h"#include "2D/Wall2D.h"#include "Path.h"#include "2D/Geometry.h"#include "ComponentListBase.h"#include "TrackComponentList.h"#include "VertexList.h"#include "StartPositionList.h"template <> GameManager* Singleton<GameManager>::pInstance = 0;// Initalize game data.void GameManager::GameInitialize(){    m_WorkWidth   = 800;    m_WorkHeight  = 600;    m_WorldWidth  = 1600;    m_WorldHeight = 1200;    m_Camera = Camera2D(m_WorldWidth, m_WorldHeight, m_WorkWidth, m_WorkHeight);    m_SelectedSection = NULL;    m_Mode            = MD_TRACK;    m_PointSize  = 5.0;    m_LineSize   = 2.0;    m_NormalSize = 5.0;}// Reset size, name, and content to create a new course.void GameManager::NewCourse(string filename, int width, int height){    m_WorldWidth  = width;    m_WorldHeight = height;    m_Camera = Camera2D(m_WorldWidth, m_WorldHeight, m_WorkWidth, m_WorkHeight);	m_Sections.clear();	m_SelectedSection = NULL;}// Update the game state each step.void GameManager::Update(int elapsedTicks){}// Render each frame.void GameManager::Render(){    m_Camera.Update();    // Push line attributes.    glPushAttrib(GL_POINT_BIT | GL_LINE_BIT);    glPointSize(m_PointSize);    glLineWidth(m_LineSize);    // Render sections.    SectConstItr sect;    for (sect = m_Sections.begin(); sect != m_Sections.end(); ++sect)    	(*sect)->Render();    RenderSelectionBox();    // Draw boundaries of world.    glLineWidth(4.0);    glBegin(GL_LINE_LOOP);        glColor3fv( C3f::RED.data() );        glVertex2f(0, 0);        glVertex2f(m_WorldWidth, 0);        glVertex2f(m_WorldWidth, m_WorldHeight);        glVertex2f(0, m_WorldHeight);    glEnd();    glPopAttrib();}void GameManager::RenderSelectionBox(){    int x, y;    Uint8 button = SDL_GetMouseState(&x, &y);    Vector2D pos(x, y);    // Transform to world coordinates.    m_Camera.Transform(pos.x, pos.y);    // If right mouse button is down, draw selection rectangle.    if ( button & SDL_BUTTON_RMASK )    {        glEnable(GL_LINE_STIPPLE);        glLineWidth(1.0);        glLineStipple(1, 0x03ff);  // 1111 1111 1100 0000        glBegin(GL_LINE_LOOP);           glColor3fv( C3f::BLACK.data() );           glVertex2f(pos.x,        pos.y);           glVertex2f(pos.x,        m_ClickPos.y);           glVertex2f(m_ClickPos.x, m_ClickPos.y);           glVertex2f(m_ClickPos.x, pos.y);        glEnd();        glDisable(GL_LINE_STIPPLE);    }}void GameManager::SelectSection(SectItr selection){    if (selection != m_SelectedSection)    {        DeselectSection();        m_SelectedSection = selection;        m_Mode = (*m_SelectedSection)->Mode();        Gui().ModeChanged(m_Mode);        (*m_SelectedSection)->onSelect();    }}void GameManager::DeselectSection(){    if (m_SelectedSection != NULL)    {        (*m_SelectedSection)->DeselectAll();        (*m_SelectedSection)->onDeselect();    }    m_SelectedSection = NULL;}void GameManager::RemoveSection(){    if (m_SelectedSection != NULL)    {        m_Sections.erase(m_SelectedSection);        m_SelectedSection = NULL;    }}// Called once when a key is pressed.void GameManager::KeyDown(int key, int mod){    switch (key)    {    /// MAP CONTROLS    /// <CTRL+N> Brings up new dialog.    case SDLK_n:        if (mod & KMOD_CTRL)            Gui().HandleEvent("open_dialog_new");        break;    /// <CTRL+O> Brings up open dialog.    case SDLK_o:        if (mod & KMOD_CTRL)            Gui().HandleEvent("open_dialog_open");        break;    /// <CTRL+S> Brings up save dialog.    case SDLK_s:        if (mod & KMOD_CTRL)            Gui().HandleEvent("open_dialog_save");        break;    /// <CTRL+H> Brings up help dialog.    case SDLK_h:        if (mod & KMOD_CTRL)            Gui().HandleEvent("open_dialog_help");        break;    /// <L> Toggle between looped or linear sections.    case SDLK_l:        Gui().HandleEvent("toggle_looped");        break;    /// <D> Reverse the direction of the section.    case SDLK_d:        Gui().HandleEvent("toggle_direction");        break;    /// <CTRL+C> Copy selected components to the clipboard.    case SDLK_c:        if (m_SelectedSection == NULL)  break;        if (mod & KMOD_CTRL)            m_Clipboard = (*m_SelectedSection)->Copy();        break;    /// <CTRL+V> Paste the component list from the clipboard.    case SDLK_v:        if (m_Clipboard == NULL)  break;        if (mod & KMOD_CTRL)        {            // Create a deep copy of the clipboard and push it in the list.            SectPtr sect( m_Clipboard->Clone() );            m_Sections.push_back(sect);            // Select the section and all of its components.            SelectSection( Last(m_Sections) );            (*m_SelectedSection)->SelectAll();        }        break;    /// <DElETE> Delete components in selected section.    /// <CTRL+DELETE> Delete entire section.    case SDLK_DELETE:        if (m_SelectedSection == NULL)  break;        if (mod & KMOD_CTRL)            RemoveSection();        else        {            (*m_SelectedSection)->Remove();            if ( (*m_SelectedSection)->Empty() )                RemoveSection();        }        DeselectSection();        break;    /// CAMERA CONTROLS    case SDLK_LEFT:        m_Camera.Scroll(-5, 0);        break;    case SDLK_RIGHT:        m_Camera.Scroll(5, 0);        break;    case SDLK_UP:        m_Camera.Scroll(0, -5);        break;    case SDLK_DOWN:        m_Camera.Scroll(0, 5);        break;    case SDLK_PAGEUP:        m_Camera.Zoom(2.0);        ResizeNormals(m_NormalSize*0.5 / m_Camera.Scale() );        break;    case SDLK_PAGEDOWN:        m_Camera.Zoom(0.5);        ResizeNormals(m_NormalSize*2.0 / m_Camera.Scale() );        break;    }}// Called once when a key is released.void GameManager::KeyUp(int key, int mod){	switch (key)	{    /// MAP CONTROLS    /// CAMERA CONTROLS	case SDLK_LEFT:        m_Camera.Stop(X);        break;	case SDLK_RIGHT:        m_Camera.Stop(X);        break;	case SDLK_UP:        m_Camera.Stop(Y);        break;	case SDLK_DOWN:        m_Camera.Stop(Y);        break;	}}// Called every time the mouse moves.void GameManager::MouseMotion(int button,                              int x,    int y,                              int relX, int relY ){    // Do not accept input outside work area.    if (x > m_WorkWidth || y > m_WorkHeight)  return;    Vector2D pos(x, y);    // Transform to world coordinates.    m_Camera.Transform(pos.x, pos.y);    // Do not accept input outside world area.    if (pos.x > m_WorldWidth || pos.y > m_WorldHeight)  return;    if (m_SelectedSection == NULL)  return;    // Left mouse button is pressed.    if ( button & SDL_BUTTON(1) )    {        if (SDL_GetModState() & KMOD_ALT)            (*m_SelectedSection)->Stretch( relY / m_Camera.Scale() );        else if (SDL_GetModState() & KMOD_SHIFT)            (*m_SelectedSection)->Rotate( relX / (50.0 * m_Camera.Scale()) );        else            (*m_SelectedSection)->Translate( Vector2D(relX, relY) / m_Camera.Scale() );    }}// Called once when a mouse button is pressed.void GameManager::MouseButtonDown(int button,                                  int x,    int y,                                  int relX, int relY ){    // Do not accept input outside work area.    if (x > m_WorkWidth || y > m_WorkHeight)  return;    Vector2D pos(x, y);    // Transform to world coordinates.    m_Camera.Transform(pos.x, pos.y);    // Do not accept input outside world area.    if (pos.x > m_WorldWidth || pos.y > m_WorldHeight)  return;    switch (button)    {        case SDL_BUTTON_LEFT:            if (SDL_GetModState() & KMOD_CTRL)            {                // If there is no selected track, create a new one.                if (m_SelectedSection == NULL)                {                    boost::shared_ptr<ComponentListBase> cl;                    switch (m_Mode)                    {                        case MD_TRACK:                            cl = boost::shared_ptr<Track>(new Track);                            break;                        case MD_PATH:                            cl = boost::shared_ptr<VertexList>(new VertexList);                            break;                        case MD_STARTS:                            cl = boost::shared_ptr<StartList>(new StartList);                            break;                        default:                            throw RuntimeError("Undefined mode.", __LINE__, __FILE__);                    }                    m_Sections.push_back(cl);                    SelectSection( Last(m_Sections) );                }                (*m_SelectedSection)->Insert(pos);            }            break;        case SDL_BUTTON_RIGHT:            // Remember the coordinates of the click.            m_ClickPos = pos;            break;    }}// Called once when a mouse button is released.void GameManager::MouseButtonUp(int button,                                int x,    int y,                                int relX, int relY ){    // Do not accept input outside work area.    if (x > m_WorkWidth || y > m_WorkHeight)  return;    Vector2D pos(x, y);    // Transform to world coordinates.    m_Camera.Transform(pos.x, pos.y);    // Do not accept input outside world area.    if (pos.x > m_WorldWidth || pos.y > m_WorldHeight)  return;    switch (button)    {        case SDL_BUTTON_LEFT:            break;        case SDL_BUTTON_RIGHT:            // Margin of error for selecting track segments.            double radius = 5.0 / m_Camera.Scale();            // If control is held, add to current selection.            if (SDL_GetModState() & KMOD_CTRL)            {                if (m_SelectedSection == NULL)  return;                // If the release was close to the press, do not treat as a                // rectangular selection.                if (pos.DistanceSq(m_ClickPos) < 25.0)                {                    // Select a track segment at mouse position.                    (*m_SelectedSection)->SetSelection(pos, radius,                                          ComponentListBase::SELECT);                }                // If the release was far from the press, the selection is a                // rectangle.                else                {                    // Create a selection rectangle and use it to select.                    Rectangle rect( MinOf(pos.x, m_ClickPos.x),    // left                                    MinOf(pos.y, m_ClickPos.y),    // top                                    MaxOf(pos.x, m_ClickPos.x),    // right                                    MaxOf(pos.y, m_ClickPos.y) );  // bottom                    (*m_SelectedSection)->SetSelection(rect,                                          ComponentListBase::SELECT);                }  // Rectangular selection            }            // If control is not held, replace the current selection.            else            {                if (m_SelectedSection != NULL)                    (*m_SelectedSection)->DeselectAll();                // If the release was close to the press, do not treat as a                // rectangular selection.                if (pos.DistanceSq(m_ClickPos) < 25.0)                {                    // Search through all sections for a matching segment.                    SectRItr s;                    for (s = m_Sections.rbegin(); s != m_Sections.rend(); )                    {                        ++s;                    	bool selected = ( *s.base() )->SetSelection(pos, radius,                                                       ComponentListBase::SELECT);                        if (selected)                        {                            SelectSection( s.base() );                            break;                        }                        DeselectSection();                    }                }                // If the release was far from the press, the selection is a                // rectangle.                else                {                    // Create a selection rectangle and use it to select.                    Rectangle rect( MinOf(pos.x, m_ClickPos.x),    // left                                    MinOf(pos.y, m_ClickPos.y),    // top                                    MaxOf(pos.x, m_ClickPos.x),    // right                                    MaxOf(pos.y, m_ClickPos.y) );  // bottom                    // Ends up true if a selection was made.                    bool selected = false;                    // Search through all tracks for a matching segment.                    SectRItr s;                    for (s = m_Sections.rbegin(); s != m_Sections.rend(); )                    {                        ++s;                    	selected = ( *s.base() )->SetSelection(rect,                                                  ComponentListBase::SELECT);                        if (selected)                        {                            SelectSection( s.base() );                            break;                        }                        DeselectSection();                    }                }  // Rectangular selection            }  // Control not held down            break;    }  // Switch button}// Unpause game.void GameManager::WindowActive(){}// Pause game.void GameManager::WindowInactive(){}// Clean up at the end of the game.void GameManager::End(){}void GameManager::ToggleLooped(){    if (m_SelectedSection == NULL)        return;    (*m_SelectedSection)->ToggleLooped();}void GameManager::ToggleDirection(){    if (m_SelectedSection == NULL)        return;    (*m_SelectedSection)->Reverse();}void GameManager::ShowComponents(bool show){    SectItr sect;    for (sect = m_Sections.begin(); sect != m_Sections.end(); ++sect)        (*sect)->ShowComponents(show);}void GameManager::ShowConnections(bool show){    SectItr sect;    for (sect = m_Sections.begin(); sect != m_Sections.end(); ++sect)        (*sect)->ShowConnections(show);}void GameManager::ResizeNormals(double) {}

The main things to look at are things involving the creation and destruction of elements in m_Sections, which occur in the mouse and keyboard event handling functions. The problem only happens when I create some tracks and paths, then a start position list, and then delete them all and exit the app.
This is something of a shot in the dark, but perhaps you should also check that the iterator is not at the end of m_Sections when calling erase:

if (m_SelectedSection != NULL && m_SelectedSections != m_Sections.end() ) {
  m_Sections.erase(m_SelectedSection);
  m_SelectedSection = NULL;
}

A null iterator is not the same as an iterator at the end of a list.

[edit] Then again, that wouldn't really explain a crash at close in this case (I don't think). Could you give the entire error message? Perhaps it's your Singleton implementation that is screwy.

[edit2] How is GDB not working?


jfl.
Quote:Original post by Mr Awesome
I'm using GDB from CodeBlocks, but it either isn't working or I don't understand how to use it.


1) compile the file with debugging information included (-g)
2) run the executable within gdb
3) reproduce the steps necessary to make the executable crash
4) check out the debugger and type "bt" (enter) (bt for "backtrace")
5) if you cannot make sense of the backtrace yourself, post it here.

HTH

PS: gdb features an awesome integrated help system that's accessible by issuing a simple "help (topic)"


Here is the output from gdb. I don't why, but there are just a ton of question marks, so it doesn't seem to help me all that much. However, it does say that there is a segfault, but usually SDL catches those. Any ideas?

gdb: Target exception EXCEPTION_ACCESS_VIOLATION at 0x10022d7c

---Type <return> to continue, or q <return> to quit---
Program received signal SIGSEGV, Segmentation fault.
0x10022d7c in SDL_UnlockSurface () from C:\WINDOWS\system32\SDL.dll
(gdb) bt
#0 0x10022d7c in SDL_UnlockSurface () from C:\WINDOWS\system32\SDL.dll
#1 0x00000000 in ?? () from
#2 0x003f63b8 in ?? ()
#3 0x1002308d in SDL_FreeSurface () from C:\WINDOWS\system32\SDL.dll
#4 0x0022fe10 in ?? ()
#5 0x00000001 in ?? ()
#6 0x0040463f in ?? ()
#7 0x003f63b8 in ?? ()
#8 0x00343834 in ?? ()
#9 0x0022fca8 in ?? ()
#10 0x00000001 in ?? ()
#11 0x00343740 in ?? ()
#12 0x00343154 in ?? ()
#13 0x0022fca8 in ?? ()
#14 0x00000001 in ?? ()
#15 0x0041fe30 in ?? ()
#16 0x0046c7b2 in ?? ()
#17 0x0022fc5c in ?? ()
#18 0x0045581d in ?? ()
#19 0x0041fe30 in ?? ()
#20 0x0046c43c in ?? ()
#21 0x0022fc6c in ?? ()
#22 0x00404646 in ?? ()
---Type <return> to continue, or q <return> to quit---
#23 0x0022fc20 in ?? ()
#24 0x0022fe10 in ?? ()
#25 0x0022fc78 in ?? ()
#26 0x00000000 in ?? () from
#27 0x00000001 in ?? ()
#28 0x0022fe10 in ?? ()
#29 0x0022fce8 in ?? ()
#30 0x0042fe60 in ?? ()
#31 0x0046e238 in ?? ()
#32 0x003f0000 in ?? ()
#33 0x00000000 in ?? () from
#34 0x77c2c2e3 in msvcrt!free () from C:\WINDOWS\system32\msvcrt.dll
#35 0x77c2c21b in msvcrt!calloc () from C:\WINDOWS\system32\msvcrt.dll
#36 0x003f4568 in ?? ()
#37 0x77c2c21b in msvcrt!calloc () from C:\WINDOWS\system32\msvcrt.dll
#38 0x7c917280 in ntdll!NtAccessCheck () from ntdll.dll
#39 0x0022fce0 in ?? ()
#40 0x77c39f8e in msvcrt!_c_exit () from C:\WINDOWS\system32\msvcrt.dll
#41 0x0022fd78 in ?? ()
#42 0xffffffff in ?? ()
#43 0x77c5f710 in msvcrt!__crtCompareStringA ()
#44 0x77c35140 in signal () from C:\WINDOWS\system32\msvcrt.dll
#45 0x10034634 in SDL_FreeYUVOverlay ()
---Type <return> to continue, or q <return> to quit---
#46 0x0041fe30 in ?? ()
#47 0x0046c7b8 in ?? ()
#48 0x0022fcdc in ?? ()
#49 0x0042fda3 in ?? ()
#50 0x0022fc80 in ?? ()
#51 0x77c35c94 in msvcrt!_except_handler2 ()
from C:\WINDOWS\system32\msvcrt.dll
Previous frame inner to this frame (corrupt stack?)

C:\C++ Programs\Games\AI Games\Course Editor>
Try getting more information about the error (in particular, the IP register value).

I'm assuming that you're using MS Visual Studio, so right click on the first line of your code, and select "Run To Cursor". From the "Debug" menu, select "Windows", and then "Disassembly". Then click the "Disassembly" tab.

In the "Address" field, type 0x???????? (whatever the value of the IP register was) and that should take you to the source of the error. With a bit of luck, it might give you a general area as to where the problem occurs.

EDIT: Doh. You're using CodeBlocks.
I'm also using gcc, if that helps any.

This topic is closed to new replies.

Advertisement