【发布时间】:2014-02-10 02:44:01
【问题描述】:
我一直在试图调查一个非常奇怪的程序崩溃。堆栈跟踪基本上是这样的
msvcr100.dll!malloc(unsigned int size) Line 89 C
msvcr100.dll!operator new(unsigned int size) Line 59 C++
msvcp100.dll!std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::_Getcat(const std::locale::facet * * _Ppf, const std::locale * _Ploc) Line 1054 C++
msvcp100.dll!std::use_facet<std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > > >(const std::locale & _Loc) Line 518 C++
msvcp100.dll!std::basic_ostream<char,std::char_traits<char> >::operator<<(int) Line 287 C++
接下来是我的代码中的一行,它只是一个简单的 cout
cout << "Error is " << ret << endl;
我无法确定导致此崩溃的原因。我知道我并没有耗尽内存,因为该进程在崩溃之前只使用了大约 2000 KB。
由于它只打印一个局部整数变量,我也没有看到涉及非法内存访问。
程序是使用带有 Win32 发布配置文件的 Visual Studio 2010 (v100) 编译的,我已确认生产服务器已安装 Microsoft Visual C++ 2010 x86 Redistributable。
我还应该在哪里寻找原因的线索?
【问题讨论】:
-
在调试模式下也可以吗?
-
我发现这类错误往往是由于缓冲区溢出或其他指针滥用以某种方式破坏 malloc 的会计数据造成的。调试 malloc 库可以帮助发现此类问题(它使用金丝雀值并进行更多的完整性检查)。换句话说,问题可能与段错误不在同一行。
-
感谢@Adam,如果程序在调试模式下编译不会发生问题。但是 VC++ 2010 redist 包不包含调试库,因此我无法将调试版本部署到生产环境。我将尝试在其他行上搜索缓冲区溢出。由于有数百行,是否有推荐的方法来查找它?
-
在没有调试库的情况下,是时候开始 ifdef'ing 代码试图缩小问题所在了。除了覆盖内存之外,您还可以双重释放某些东西。
-
@gerrytan VC redist 包可能没有做足够的检查,即使是调试版本。自从我为 Windows 开发以来已经有一段时间了,但在 Unix 上,您可以将自己的
malloc预先链接到任何进程。实际上,这就是我们学习构建 malloc 的方式。所以有几个这样的调试库可用,最常见的是valgrind。它做得更多,但它也可以做到这一点。我不知道是否有 Windows 版本,但肯定应该有一个等价的。它将执行所有提到的检查以及更多检查,您可以针对它运行您的发布代码。
标签: c++ visual-c++