如何在应用程序启动时打破堆栈

时间:2017-03-24 22:02:32

标签: c++ mfc windbg

堆栈帧指针(EBP)应始终指向前一个堆栈帧正确的位置,但为什么我的应用程序不是这种情况!这表明事情确实是错误的......难以置信!

我创建了多个简单的演示应用程序,其中堆栈指针始终指向前一个堆栈帧,但我无法理解为什么在这个应用程序中不是这种情况,并且当我的应用程序刚刚启动时就会发生这种情况! / p>

以下是我的调用堆栈

0:000> k
 # ChildEBP RetAddr  
00 0018fee4 6381d1cd acn!CAcnApp::InitInstance+0x41 [c:\acn-project\acn\acn.cpp @ 527]
01 0018fef4 00428575 MFC80U!AfxWinMain+0x48 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\winmain.cpp @ 37]
02 0018ff88 765d336a acn!__tmainCRTStartup+0x150 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 589]
03 0018ff94 76f59902 kernel32!BaseThreadInitThunk+0xe
04 0018ffd4 76f598d5 ntdll!__RtlUserThreadStart+0x70
05 0018ffec 00000000 ntdll!_RtlUserThreadStart+0x1b
0:000> dc 0018fee4 
0018fee4  ffffffff 6381d1cd 00489498 00000001  .......c..H.....
0018fef4  00000000 00428575 00400000 00000000  ....u.B...@.....
0018ff04  01e53fd2 0000000a 87b8aee0 00000000  .?..............
0018ff14  00000000 7efde000 00000044 01e54012  .......~D....@..
0018ff24  01e53ff2 01e53fd4 00000000 00000000  .?...?..........
0018ff34  00000000 00000000 00000000 00000000  ................
0018ff44  00000000 00000000 00000000 00000000  ................
0018ff54  00000000 00000000 0018ff84 00428e5d  ............].B.
0:000> dc 0018fef4 
0018fef4  00000000 00428575 00400000 00000000  ....u.B...@.....
0018ff04  01e53fd2 0000000a 87b8aee0 00000000  .?..............
0018ff14  00000000 7efde000 00000044 01e54012  .......~D....@..
0018ff24  01e53ff2 01e53fd4 00000000 00000000  .?...?..........
0018ff34  00000000 00000000 00000000 00000000  ................
0018ff44  00000000 00000000 00000000 00000000  ................
0018ff54  00000000 00000000 0018ff84 00428e5d  ............].B.
0018ff64  01e53fd2 00000000 00000000 0018ff0c  .?..............
0:000> dc 0018ff88 
0018ff88  0018ff94 765d336a 7efde000 0018ffd4  ....j3]v...~....
0018ff98  76f59902 7efde000 7d7a657d 00000000  ...v...~}ez}....
0018ffa8  00000000 7efde000 00000000 00000000  .......~........
0018ffb8  00000000 0018ffa0 00000000 ffffffff  ................
0018ffc8  76f958c5 0b965c89 00000000 0018ffec  .X.v.\..........
0018ffd8  76f598d5 0042873d 7efde000 00000000  ...v=.B....~....
0018ffe8  00000000 00000000 00000000 0042873d  ............=.B.
0018fff8  7efde000 00000000 78746341 00000020  ...~....Actx ...

控件位于InitInstance()的第一行,所以就像我的应用程序正在吸取第一个呼吸并且堆栈似乎已经损坏了?那么app类构造函数就在此之前,但我检查了调用堆栈在那里也处于类似的状态。

请注意,第1帧和第2帧的堆栈帧指针(EFP)检查都会失败,但堆栈是否超出此范围。

我的第一个问题是,是否有任何解释,调用堆栈可以像这样,这是好的?换句话说,我们可以说调用堆栈肯定会被破坏吗?应用程序会加载并调用各种dll,如果它可能起任何作用(不知道为什么会这样)。

在这种情况下,由于应用程序刚刚开始,可能是什么嫌疑人??

更新(代码)

这是非常简单的构造函数。至于InitInstance(),那个函数很长,但我的断点在第一行,所以当调用堆栈就是这样时,它的代码永远不会被执行。

CAcnApp::CAcnApp()
{
    m_bServMode = FALSE;
    m_bFactory = FALSE;
    m_bDownload = FALSE;
    m_pEngine = NULL;
    m_hWiztomMod = NULL;
    m_pServer = new CAcnServer;
}

第二次更新

我发布了一个跟进question,以便在进一步调查后分享额外信息,由于存在差异,这确实有资格作为单独的问题。

1 个答案:

答案 0 :(得分:1)

BTW,在调用main函数之前创建全局或文件全局对象。

如果对象的构造函数有问题,您可以在调用main之前看到任何数量的缺陷。

检查对象的构造函数。您应该能够在对象的构造函数中设置断点。

编辑1:构造函数中的内存分配
拥有动态内存分配的全局对象可能会导致问题。该对象要求在构造对象之前初始化动态内存分配。尝试注释掉动态内存分配,看看问题是否消失。

解决方法是创建一个“初始化”方法,该方法可在达到main入口点后调用。 initialize方法将执行动态内存分配。