在MFC应用中,Stack Overflow C00000FD。

时间:2022-10-05 17:02:21

I am using a Custom tree control derived class. Below is the code.

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

CCustomTreeCtrl.h

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.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);
            }
         }
      }

   }
}

The application exits on double click on a tree item. When debugging, on stepping into the CreateFile function raises ans stack overflow exception.

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

If the file is up to date the DisplayFile function is executed properly.

如果文件是最新的,DisplayFile函数将被正确执行。

The error is only when I call the CreateFile function. The function just writes some data to text file. On debugging, the exception is raised the minute I step into the function.

当我调用CreateFile函数时,错误才会出现。函数只是将一些数据写入文本文件。在调试过程中,当我进入函数时,异常会被提高。

Call Trace (IDE VC6)

调用跟踪机器(IDE)

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

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 Yes, the application crashes before hitting the breakpoint.

是的,应用程序在到达断点之前崩溃。

In Disassembly:

在拆卸:

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)

As soon as i step into Create File function, in the variable window its showing "this CXX0069: Error variable needs stack frame"

当我进入创建文件函数时,在变量窗口中显示“this CXX0069:错误变量需要堆栈帧”

CreateFile Disassembly:

它仅仅拆卸:

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

Currently I don't have the source of the CMyDllx. Only the header and lib. But I am also calling the same function from the application menu, it get carried out without any error. Its only when I call it using tree control, I face the error.

目前我没有CMyDllx的源代码。但是我也从应用程序菜单中调用了相同的函数,它是在没有任何错误的情况下执行的。只有当我使用树控件调用它时,我才会面对错误。

@IInspectable Sorry but this is work PC, and I cannot install any software in this machine.

对不起,这是工作PC,我不能在这台机器上安装任何软件。

1 个解决方案

#1


1  

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

109DC8h tells the tale, the argument passed to __chkstk() is the amount of stack space that CreateFile() requires. 0x109dc8 == 1,088,968 bytes. No can do, that's more than the entire space available in the stack (1 megabyte). So __chkstk() correctly slams the emergency stop button before your program hits the wall, CreateFile() will always fail.

109DC8h讲述了这个故事,传递给__chkstk()的参数是CreateFile()需要的堆栈空间的数量。0 x109dc8 = = 1088968字节。不可以,这比堆栈中可用的整个空间(1兆字节)要多。因此,__chkstk()在您的程序到达墙之前正确地抛出紧急停止按钮,CreateFile()将总是失败。

Your snippet squarely points the finger at the guilty party, it is one of the CMyDllx objects that is too big. Or more likely, all of them, needing a quarter of a megabyte each. Rewrite the code to allocate them on the free store with the new operator.

你的代码片段直接指向了有罪的一方,它是一个太大的CMyDllx对象。或者更有可能的是,它们都需要1 / 4兆字节。重写代码,将它们分配到与新操作符的空闲存储区。

#1


1  

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

109DC8h tells the tale, the argument passed to __chkstk() is the amount of stack space that CreateFile() requires. 0x109dc8 == 1,088,968 bytes. No can do, that's more than the entire space available in the stack (1 megabyte). So __chkstk() correctly slams the emergency stop button before your program hits the wall, CreateFile() will always fail.

109DC8h讲述了这个故事,传递给__chkstk()的参数是CreateFile()需要的堆栈空间的数量。0 x109dc8 = = 1088968字节。不可以,这比堆栈中可用的整个空间(1兆字节)要多。因此,__chkstk()在您的程序到达墙之前正确地抛出紧急停止按钮,CreateFile()将总是失败。

Your snippet squarely points the finger at the guilty party, it is one of the CMyDllx objects that is too big. Or more likely, all of them, needing a quarter of a megabyte each. Rewrite the code to allocate them on the free store with the new operator.

你的代码片段直接指向了有罪的一方,它是一个太大的CMyDllx对象。或者更有可能的是,它们都需要1 / 4兆字节。重写代码,将它们分配到与新操作符的空闲存储区。