MFC应用程序中的Stack Overflow C00000FD

时间:2015-11-27 10:20:41

标签: c++ mfc

我正在使用自定义树控件派生类。以下是代码。

CCustomTreeCtrl.h

class CCustomTreeCtrl : public CTreeCtrl
{
public:
    BOOL Check;
    CCustomTreeCtrl();
    virtual ~CCustomTreeCtrl();

protected:
    //{{AFX_MSG(CCustomTreeCtrl)
    afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP();
};

CCustomTreeCtrl.cpp

CCustomTreeCtrl::CCustomTreeCtrl()
{
}

CCustomTreeCtrl::~CCustomTreeCtrl()
{
}

BEGIN_MESSAGE_MAP(CCustomTreeCtrl , CTreeCtrl)
//{{AFX_MSG(CCustomTreeCtrl)
ON_WM_LBUTTONDBLCLK()
 //}}AFX_MSG
END_MESSAGE_MAP()

void CCustomTreeCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
{
   char buf[255];
   FILE *stream;
   CString FilePath;
   TV_HITTESTINFO pHitTestInfo;
   pHittestInfo.pt = point;
   pHitTestInfo.flags = TVHT_ONITEMLABEL;
   HitTest(&pHitTestInfo);

   if(pHitTestInfo.hItem != NULL && !ItemHasChildren(pHitTestInfo.hItem))
   {
      RECT sRect;
      GetItemRect(pHitTestInfo.hItem,&sRect,1);
      CRect cRect(&sRect);

      if(cRect.PtInRect(point))
      {
         CTestApp* the = (CTestApp*)AfxGetApp();
         CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();

         CString FileName = GetItemtext(pHitTestInfo.hItem);

         FilePath = pFrame->Filepath;
         strcpy(buf,Filepath);
         strcat(buf,Filename);
         strcat(buf,".ext");

         stream = fopen(buf, "r");

         if(stream != NULL)
         {
            fclose(stream);

            if(pFrame->isUpToDate(buf))
            {
               pFrame->DisplayFile(buf);
            }
            else
            {
               pFrame->CreateFile(buf);//-> Error in this line Exception: C00000FD Stack OverFlow
               pFrame->DisplayFile(buf);
            }
         }
      }

   }
}

双击树项目时,应用程序退出。 调试时,在进入CreateFile函数时会引发ans堆栈溢出异常。

如果文件是最新的,则DisplayFile功能正确执行。

只有在我调用CreateFile函数时才会出错。该函数只是将一些数据写入文本文件。在调试时,在我进入函数的那一刻就会引发异常。

调用跟踪(IDE VC6)

CCustomTreeCtrl::OnLButtonDblClick(unsigned int 1, Cpoint {x=150 y=104}) line 117
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
USER32! xxxxxxxx()
USER32! xxxxxxxx()
USER32! xxxxxxxx()
USER32! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
CTestApp::PreTranslateMessage(tagMSG * 0x00484cd0 {msg = 0x00000203 wp = 0x00000001 lp= 0x00680096}) line 563
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
WinMain(HINSTANCE__ 0x00400000, HINSTANCE__ 0x00000000, char * 0x00151f2e, int 1) Line 30
WinMainCRTStartup() Line 330 + 54 bytes
KERNEL32! xxxxxxxx()

CreateFunction

void CMainFrame::CreateFile(CString FileName)
{
    BeginWaitCursor();

    if(FileName.getAt(1) == 'L')
    {
        CMyDllA myDlla;
        myDlla.ConvertDataToFile(MyDataBasePath,FileName);
    }
    else if(FileName.getAt(1) == 'B')
    {
        CMyDllB myDllb;
        myDllb.ConvertDataToFile(MyDataBasePath,FileName);
    }
    else if(FileName.getAt(1) == 'D')
    {
        CMyDllD myDlld;
        myDlld.ConvertDataToFile(MyDataBasePath,FileName);
    }
    else if(FileName.getAt(1) == 'S')
    {
        CMyDllS myDlls;
        myDlls.ConvertDataToFile(MyDataBasePath,FileName);
    }

    EndWaitCursor();
}

//ConvertDataToFile Function reads data for a database performs calculations and writes report to a text file.

@Michael Walz是的,应用程序在遇到断点之前崩溃了。

在反汇编中:

147       pFrame->CreateFile(buf);
00456B74 push ecx
00456B75 mov  ecx,esp
00456B77 mov  dword ptr [ebp-112A8h],esp
00456B7D lea  edx, [buf]
00456B83 push edx
00456B84 call CString::CString (0045da26)
00456B89 mov  dword ptr [ebp-11328h],eap
00456B77 mov  ecx, dword ptr [pFrame]
00456B95 call @ILT+1300(CMainFrame::CreateFile) (00401519)

当我进入创建文件功能时,在变量窗口中显示"此CXX0069:错误变量需要堆栈帧"

CreateFile反汇编:

10040: {
0043F813 push ebp
0043F814 mov  ebp, esp
0043F816 push 0FFh
0043F818 push offset $L111205 (00465099)
0043F81D mov  eax, fs:[00000000]
0043F823 push eax
0043F824 mov  dword ptr fs:[0],esp
0043F824 mov  eax, 109DC8h
0043F830 call $$$00001 (0045e840)  //Breaks here and jumps to CHKSTK.ASM File
0043F835 mov  dword ptr [ebp-109DBCh], ecx
0043F83B mov  dword ptr [ebp-4], 0

目前我还没有CMyDllx的来源。只有标题和lib。 但我也从应用程序菜单调用相同的功能,它没有任何错误执行。只有当我使用树控件调用它时,我才会遇到错误。

@IInspectable抱歉,这是工作PC,我无法在此机器上安装任何软件。

1 个答案:

答案 0 :(得分:1)

0043F824 mov  eax, 109DC8h
0043F830 call $$$00001 (0045e840)  //Breaks here and jumps to CHKSTK.ASM File

109DC8h告诉传说,传递给__chkstk()的参数是CreateFile()所需的堆栈空间量。 0x109dc8 == 1,088,968字节。不可以,这比堆栈中可用的整个空间(1兆字节)更重要。所以__chkstk()在你的程序碰到墙之前正确地猛击紧急停止按钮,CreateFile()总是会失败。

你的片段直接指向有罪的一方,它是一个太大的CMyDllx对象。或者更有可能的是,所有这些都需要四分之一兆字节。重写代码以使用new运算符在免费商店中分配它们。