Newbie Debugger Question???

Started by
8 comments, last by Tarpedoe81 15 years, 9 months ago
When I compiled my program, it finished without any problems. But then, in the Output window, I selected "debug" in the drop-down text box, it displayed the symbols loaded/unloaded, but it also displayed this: "Game Files.exe': Loaded 'C:\WINDOWS\system32\wbsys.dll', Binary was not built with debug information. First-chance exception at 0x7c918fea in Game Files.exe: 0xC0000005: Access violation writing location 0x00000010." Can anybody tell me what these two sentences mean??? I think the "first-chance exception" is a memory leak, but any kind of input would help. Thanks. Here is my code:
 
// Core_System.h
// Handles Windows processing, registers the window class,
// creates the applicatiion window, and deals with states, 
// processes, and data packages.

#include <windows.h>

#ifndef SYSTEM_H
#define SYSTEM_H

class cApplication
{
private:
    HINSTANCE	m_hInst; // Instance handle
    HWND	m_hWnd; // Window handle

protected:
    char	m_Class[MAX_PATH]; // Class name
    char	m_Caption[MAX_PATH]; // Window caption

    WNDCLASSEX	m_wcex; // Windows class structure

    DWORD	m_Style; // Window style
    DWORD	m_XPos; // X coordinate of window
    DWORD	m_YPos; // Y coordinate of window
    DWORD	m_Width; // Default width of window
    DWORD	m_Height; // Default height of window

  public:
    cApplication(); // Constructor

    HWND GethWnd(); // Returns window handle
    HINSTANCE GethInst(); // Returns instance handle

    BOOL Run(); // Executes class code
    BOOL Error(BOOL Fatal, char *Text, ...); // Prints error
    
    BOOL Move(long XPos, long YPos); // Move window
    BOOL Resize(long Width, long Height); // Resize client area

    BOOL ShowMouse(BOOL Show = TRUE); // Show or hide cursor

    // Default message handler
    virtual LRESULT CALLBACK MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
    { 
	return DefWindowProc(hWnd, uMsg, wParam, lParam); 
    }

    // Custom functions that will hold your game code
    virtual BOOL Init()     { return TRUE; }
    virtual BOOL Shutdown()	{ return TRUE; }
    virtual BOOL Frame()    { return TRUE; }
};

// Static pointer to class
static cApplication *g_pApplication = new cApplication;

// Overloaded message procedure
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

enum Purpose 
{
    NOPURPOSE = 0,
    INITPURPOSE,
    SHUTDOWNPURPOSE,
    FRAMEPURPOSE
};
    
class cStateManager
{
  typedef struct sState 
  {
    void (*Function)(void *Ptr, long Purpose);
    sState *Next;

    sState()
    {
      Function = NULL;
      Next = NULL;
    }

    ~sState()
    {
      delete Next;
    }
  } sState;

  protected:
    sState *m_StateParent;

  public:
    cStateManager();
    ~cStateManager();

    void Push(void (*Function)(void *Ptr, long Purpose), void *DataPtr = NULL);
    BOOL Pop(void *DataPtr = NULL);
    void PopAll(void *DataPtr = NULL);
    BOOL Process(void *DataPtr = NULL);
};

class cProcessManager
{
  typedef struct sProcess 
  {
    void  (*Function)(void *Ptr, long Purpose);
    sProcess *Next;

    sProcess()
    {
      Function = NULL;
      Next = NULL;
    }

    ~sProcess()
    {
      delete Next;
    }
  } sProcess;

  protected:
    sProcess *m_ProcessParent; 

  public:
    cProcessManager();
    ~cProcessManager();

    void Push(void (*Process)(void *Ptr, long Purpose), void *DataPtr = NULL);
    BOOL Pop(void *DataPtr = NULL);
    void PopAll(void *DataPtr = NULL);
    void Process(void *Ptr = NULL);
};

class cDataPackage
{
  protected:
    void          *m_Buf;
    unsigned long  m_Size;

  public:
    cDataPackage();
    ~cDataPackage();

    void *Create(unsigned long Size);
    void Free();

    BOOL Save(char *Filename);
    void *Load(char *Filename, unsigned long *Size);

    void          *GetPtr();
    unsigned long  GetSize();
}; 

#endif

 
// Core_System.cpp

#include "Core_System.h"
#include <windows.h>
#include <stdio.h>

cApplication::cApplication()
{
  // Save instance handle
  g_pApplication = this;

  // Get the instance handle
  m_hInst = GetModuleHandle(NULL);

  // Set a default window class and caption
  strcpy(m_Class, "AppClass");
  strcpy(m_Caption, "Application Caption");

  // Set default window style, position, width, height
  m_Style  = WS_OVERLAPPEDWINDOW;
  m_XPos   = 0;
  m_YPos   = 0;
  m_Width  = 256;
  m_Height = 256;

  // Set default WNDCLASSEX structure
  m_wcex.cbSize        = sizeof(WNDCLASSEX);
  m_wcex.style         = CS_CLASSDC;
  m_wcex.lpfnWndProc   = WindowProc;
  m_wcex.cbClsExtra    = 0;
  m_wcex.cbWndExtra    = 0;
  m_wcex.hInstance     = m_hInst;
  m_wcex.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  m_wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);
  m_wcex.hbrBackground = NULL;
  m_wcex.lpszMenuName  = NULL;
  m_wcex.lpszClassName = m_Class;
  m_wcex.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
}

HWND cApplication::GethWnd()
{
  return m_hWnd;
}

HINSTANCE cApplication::GethInst()
{
  return m_hInst;
}

BOOL cApplication::Run()
{
  MSG Msg;

  // Register window class
  if(!RegisterClassEx(&m_wcex))
    return FALSE;

  // Create the Main Window
  m_hWnd = CreateWindow(m_Class, m_Caption,
        m_Style, 
        m_XPos, m_YPos,
        m_Width, m_Height,
        NULL, NULL, m_hInst, NULL);
  if(!m_hWnd)
    return FALSE;

  // Show and update the window
  ShowWindow(m_hWnd, SW_NORMAL);
  UpdateWindow(m_hWnd);

  // Make sure client area is correct size
  Resize(m_Width, m_Height);

  // Initialize COM
  CoInitialize(NULL);

  if(Init() == TRUE) {
     // Enter the message pump
    ZeroMemory(&Msg, sizeof(MSG));
    while(Msg.message != WM_QUIT) {

      // Handle Windows messages (if any)
      if(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
      } else {
        // Do per-frame processing, break on FALSE return value
        if(Frame() == FALSE)
          break;
      }
    }
  }

  Shutdown();

  // Shutdown COM
  CoUninitialize();

  // Unregister the window class
  UnregisterClass(m_Class, m_hInst);

  return TRUE;
}

BOOL cApplication::Error(BOOL Fatal, char *Text, ...)
{
  char CaptionText[12];
  char ErrorText[2048];
  va_list valist;

  // Build the message box caption based on fatal flag
  if(Fatal == FALSE)
    strcpy(CaptionText, "Error");
  else 
    strcpy(CaptionText, "Fatal Error");

  // Build variable text buffer
  va_start(valist, Text);
  vsprintf(ErrorText, Text, valist);
  va_end(valist);

  // Display the message box
  MessageBox(NULL, ErrorText, CaptionText, MB_OK | MB_ICONEXCLAMATION);

  // Post a quit message if error was fatal
  if(Fatal == TRUE)
    PostQuitMessage(0);

  return TRUE;
}

BOOL cApplication::Move(long XPos, long YPos)
{
  RECT ClientRect;

  GetClientRect(m_hWnd, &ClientRect);
  MoveWindow(m_hWnd, XPos, YPos, ClientRect.right, ClientRect.bottom, TRUE);

  return TRUE;
}

BOOL cApplication::Resize(long Width, long Height)
{
  RECT WndRect, ClientRect;
  long WndWidth, WndHeight;

  GetWindowRect(m_hWnd, &WndRect);
  GetClientRect(m_hWnd, &ClientRect);

  WndWidth  = (WndRect.right  - (ClientRect.right  - Width))  - WndRect.left;
  WndHeight = (WndRect.bottom - (ClientRect.bottom - Height)) - WndRect.top;

  MoveWindow(m_hWnd, WndRect.left, WndRect.top, WndWidth, WndHeight, TRUE);

  return TRUE;
}

BOOL cApplication::ShowMouse(BOOL Show)
{
  ShowCursor(Show);
  return TRUE;
}

// The message procedure - empty except for destroy message
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch(uMsg) {
    case WM_DESTROY:
      PostQuitMessage(0);
      return 0;

    default: return g_pApplication->MsgProc(hWnd, uMsg, wParam, lParam);
  }
}

cStateManager::cStateManager() 
{ 
  m_StateParent = NULL; 
}

cStateManager::~cStateManager() 
{
  PopAll();
}

// Push a function on to the stack
void cStateManager::Push(void (*Function)(void *Ptr, long Purpose), void *DataPtr)
{
  sState *StatePtr;

  // Don't push a NULL value
  if(Function != NULL) {
    // Allocate a new state and push it on stack
    StatePtr = new sState();

    StatePtr->Function = Function;
    StatePtr->Next = m_StateParent;

    m_StateParent = StatePtr;

    // Call state with init purpose
    StatePtr->Function(DataPtr, INITPURPOSE);
  }
}

BOOL cStateManager::Pop(void *DataPtr)
{
  sState *StatePtr;

  // Remove the head of stack (if any)
  if((StatePtr = m_StateParent) != NULL) {
    // First call with shutdown purpose
    m_StateParent->Function(DataPtr, SHUTDOWNPURPOSE);

    m_StateParent = StatePtr->Next;
    StatePtr->Next = NULL;
    delete StatePtr;
  }

  // return TRUE if more states exist, FALSE otherwise
  if(m_StateParent == NULL)
    return FALSE;
  return TRUE;
}

void cStateManager::PopAll(void *DataPtr)
{
  while(Pop(DataPtr) == TRUE);
}

BOOL cStateManager::Process(void *DataPtr)
{ 
  // return an error if no more states
  if(m_StateParent == NULL)
    return FALSE;

  // Process the top-most state
  m_StateParent->Function(DataPtr, FRAMEPURPOSE); 

  return TRUE;
}

cProcessManager::cProcessManager() 
{ 
  m_ProcessParent = NULL; 
}

cProcessManager::~cProcessManager() 
{
  // Pop each process
  while(Pop()==TRUE);
}

// Push a function on to the stack
void cProcessManager::Push(void (*Process)(void *Ptr, long Purpose), void *DataPtr)
{
  // Don't push a NULL value
  if(Process != NULL) {
    // Allocate a new process and push it on stack
    sProcess *ProcessPtr = new sProcess();
    ProcessPtr->Function = Process;
    ProcessPtr->Next = m_ProcessParent;
    m_ProcessParent = ProcessPtr;

    // Call process with init purpose
    ProcessPtr->Function(DataPtr, INITPURPOSE);
  }
}

// Pop top process from stack
BOOL cProcessManager::Pop(void *DataPtr)
{
  sProcess *ProcessPtr;

  // Remove the head of stack (if any)
  if((ProcessPtr = m_ProcessParent) != NULL) {
    // First call with shutdown purpose
    m_ProcessParent->Function(DataPtr, SHUTDOWNPURPOSE);

    m_ProcessParent = ProcessPtr->Next;
    ProcessPtr->Next = NULL;
    delete ProcessPtr;
  }

  // return TRUE if more processes exist, FALSE otherwise
  if(m_ProcessParent == NULL)
    return FALSE;
  return TRUE;
}

void cProcessManager::PopAll(void *DataPtr)
{
  while(Pop(DataPtr) == TRUE);
}

// Process all functions
void cProcessManager::Process(void *DataPtr)
{ 
  sProcess *ProcessPtr = m_ProcessParent;

  while(ProcessPtr != NULL) {
    ProcessPtr->Function(DataPtr, FRAMEPURPOSE);
    ProcessPtr = ProcessPtr->Next;
  }
}

cDataPackage::cDataPackage()  
{  
  m_Buf = NULL; 
  m_Size = 0; 
}

cDataPackage::~cDataPackage() 
{ 
  Free(); 
}

void *cDataPackage::Create(unsigned long Size)
{
  // Free a previously created buffer
  Free();

  // Allocate some memory and return a pointer
  return (m_Buf = (void*)new char[(m_Size = Size)]);
}

// Free the allocated memory
void cDataPackage::Free() 
{ 
  delete m_Buf; 
  m_Buf = NULL; 
  m_Size = 0; 
}

BOOL cDataPackage::Save(char *Filename)
{
  FILE *fp;

  // Make sure there's something to write
  if(m_Buf != NULL && m_Size) {
    // Open file, write size and data
    if((fp=fopen(Filename, "wb")) != NULL) {
      fwrite(&m_Size, 1, 4, fp);
      fwrite(m_Buf, 1, m_Size, fp);
      fclose(fp);
      return TRUE;
    }
  }

  return FALSE;
}

void *cDataPackage::Load(char *Filename, unsigned long *Size)
{
  FILE *fp;

  // Free a prior buffer
  Free();

  if((fp=fopen(Filename, "rb"))!=NULL) {
    // Read in size and data
    fread(&m_Size, 1, 4, fp);
    if((m_Buf = (void*)new char[m_Size]) != NULL)
      fread(m_Buf, 1, m_Size, fp);
    fclose(fp);

    // Store size to return
    if(Size != NULL)
      *Size = m_Size;

    // return pointer
    return m_Buf;
  }

  return NULL;
}

void *cDataPackage::GetPtr()
{
  return m_Buf;
}

unsigned long cDataPackage::GetSize()
{
  return m_Size;
}


// WinMain.cpp
// Application entry point

// Include files
#include <windows.h>
#include <stdio.h>
#include <d3d8.h>
#include <d3dx8.h>
#include <dinput.h>
#include <dsound.h>
#include <dmusici.h>
#include <dpaddr.h>
#include <dplay8.h>
#include "Core_System.h"

class cApp : public cApplication
{
private:

public:
	cApp(); // Constructor

	BOOL Init(); // Overloaded Init function
	BOOL Shutdown(); // Overloaded Shutdown function
	BOOL Frame(); // Overloaded Frame function
};

cApp::cApp()
{
}

BOOL cApp::Init()
{
	return TRUE;
}

BOOL cApp::Shutdown()
{
	return TRUE;
}

BOOL cApp::Frame()
{
	return TRUE;
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int nShowCmd)
{
	cApp	App;
	return App.Run();
}

Advertisement
Notice the address of what it is trying to write to - it isn't within the normal user mode address space. Somewhere you are trying to dereference an uninitialized pointer...

//edit. Rereading your post:
Quote:Game Files.exe': Loaded 'C:\WINDOWS\system32\wbsys.dll', Binary was not built with debug information.

That is window's blinds skinning engine IIRC. Disable wb and see if the problem is still around.

However, a guess is that there is something wrong with your windows initialization routine, and which is in turn using an unitialized pointer somewhere...As the code is dying in wb I think, judging from the address
The first one just means that wbsys.dll doesn't have any debug information in it, which is nothing to worry about because it's a system DLL.

The second one means - as _Sigma said - that you're using a null pointer. Somewhere you're writing to a variable that's 0x10 (16 in decimal) bytes from the start of a struct or class, and the struct or class you're referencing is null.
When your app is trying to crash Windows does the following:

It notifies the debugger that the crash happened (this is the "first-chance").
It checks to see if there are any exception handlers that are willing to handle this.
If nobody handles it the debugger is notified again (this is called "second-chance").
If there's no debugger or it doesn't do some magic then you get the "your app crashed" system dialog.

If you're using MSVC you can go to Debug->Exceptions->Win32 and make sure there's a check next to "Access violation". That will cause the debugger to show you the exact line that caused the problem before any other code gets around to hiding it.
-Mike
Quote:Original post by Anon Mike
If you're using MSVC you can go to Debug->Exceptions->Win32 and make sure there's a check next to "Access violation". That will cause the debugger to show you the exact line that caused the problem before any other code gets around to hiding it.

Cool tip, I didn't know that!
Quote:Original post by Anon Mike
If you're using MSVC you can go to Debug->Exceptions->Win32 and make sure there's a check next to "Access violation". That will cause the debugger to show you the exact line that caused the problem before any other code gets around to hiding it.


I put the check next "Access violation", and re-ran the program. The "first-chance exception" message box came up. I pressed the break button and it brought me to the Disassmbly tab; the "show next statement arrow" pointed to this line:

"0x7c918fea inc dword ptr [eax + 10h]"

I'm not familiar with assembly language, can anybody tell me what that line means. Thanks.
Quote:First-chance exception at 0x7c918fea in Game Files.exe: 0xC0000005: Access violation writing location 0x00000010."

Quote:0x7c918fea inc dword ptr [eax + 10h]

At the address 0x7c918fea in memory, the code is trying to increment a DWORD at a 0x10 offset from the address held in the eax register.
We already more or less knew this from your original post.

The code that is dying isn't your code. Your code is calling something incorrectly and it is dying. Take a look at the call stack. Where are you? Call stack goes up, so you'll have to look down the list. go the the topmost function that you wrote and start setting break points, and start looking at values to see where this null pointer is arising.
O.K... I've added breakpoints to all of the lines in the code. The message box, that shows the exception, pops up right after the symbols are loaded. When I clicked on "break", it brought me to the disassembly window. Then I looked in the "call stack window" and the top most function was "ntdll.dll!7c918fea()".
When I looked down the list, I saw the different symbols being loaded (e.g. kernel32.dll, advapi32.dll, etc.). It didn't show any of my code on the stack.
Could this be a corrupted DLL file or something more?
I took your code, minus the directX includes, and successfully compiled and ran it under Vista x64 + VS2008, as well as XP SP2 x86 + VS2005 (which, btw, is running windows blinds). Both release & debug.

So...This leads me to believe that the code is fine, but there is something wrong with your system.

What compiler are you using?

The dll you originally quoted is the Windows Blinds dll. Are you running WB? If so, try disabling it (ie, unload it) then try rebuilding and rerunning. Also, if that doesn't work, try uninstalling it then giving it a whirl.

Failing that, is what you posted the code that you are using? Nothing more?

I suppose the only other point of interest is that the window that is created doesn't have an inside( that is to say, it only has a window border). It is transparent under vista and under xp it just picks up w/e was under it upon window creation. Was this on purpose?

Alright I found the solution to the problem. I put comments around my COM initialization and shutdown, then reran it, and the access violation didn't show up. So, then it must be a system error. But, I was wondering how can I fix the error; because I'll be using DirectX Audio, I'll need to create COM interfaces with CoCreateInstance(). Thanks.

This topic is closed to new replies.

Advertisement