【发布时间】:2015-11-20 21:57:30
【问题描述】:
当 C++ 控制台应用程序构建并启动但不会运行任何代码(至少不是调试器可以看到的任何代码)时,可以做什么?我有一个带有主要功能的程序:
int main (int argc, char *argv[])
{
short retval = 0;
retval = samain ( (short) argc, argv);
return ((int) retval);
}
为了安全起见,我在第一行 (retval=0) 和之后的行上设置了一个断点,然后运行。它显示一个控制台窗口并挂起,直到我停止调试器。调试输出显示了许多正在加载的 DLL,但没有其他内容。它以这行结尾,看起来与之前的几十行非常相似:
'fcmtsysmd.exe' (Win32): Loaded 'C:\Windows\SysWOW64\RpcRtRemote.dll'. Cannot find or open the PDB file.
我知道这是一个在“正常”环境中运行和运行的程序,因为有数百人在使用它,而我没有更改代码。我的环境中的不同之处(因为我正在重写我们的安装过程)是:
- 我可能没有正确安装所有依赖项。
- 之前导致错误的 DLL 依赖项之一已被新构建的版本替换,该版本具有独立的 COM 引用,而不是其通常的 COM 引用,因为它试图访问的 COM 对象未注册。 (我正在尝试在我们的新安装中实现隔离 COM。)
所以我的问题是,如果在执行第一行代码之前发生错误,我该如何追查问题的根源?
我无法获得合理的调用堆栈,因为即使我单步(F10 键)启动程序,它也会立即挂起。如果我在那一点上中断,我会看到以下调用堆栈:
ntdll.dll!7743fdd1() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7743fdd1() Unknown
ntdll.dll!77475f86() Unknown
ntdll.dll!77459809() Unknown
当我从依赖 DLL 中删除隔离的 COM 设置时,我可能会遇到访问冲突异常并停止调试器中的某些代码。它在另一个 DLL 中的静态变量初始化期间被调用的函数停止。奇怪的是,当我将隔离的 COM 设置添加到第一个 DLL 并在另一个 DLL 上放置断点时,断点甚至没有被命中。
【问题讨论】:
-
有没有机会叠起来呢?
-
如果你在调试器内部中断,它应该通过查看堆栈跟踪告诉你它在哪里停止。它可能在由静态对象初始化调用的函数内部。确保您正在运行调试构建,否则断点将不可靠。
-
这是病毒扫描程序的问题吗?
-
最好的办法是在depends.exe 中加载这个模块并查看所有依赖项。如果它报告任何缺少的依赖项,请将这些库复制到与此 exe 相同的文件夹中并重新运行
-
我禁用了 McAffee On Access Scan 并得到了相同的结果。
标签: c++ debugging visual-studio-2013