我在VS2015上加载了一个解决方案,当我退出并附带调试器时,它会在退出和清理后崩溃。 VS2012上的相同解决方案不会崩溃,也不会附加调试器。
崩溃似乎与标准输入和输出流的关闭有关,但认为我不使用它们(据我所知;它可能被用于某些附加的库,如png,jpg ,postgres ......)。
// Closes the underlying OS file handle, if and only if nt needs to be closed.
// Returns 0 on success; returns the OS error on failure.
static DWORD close_os_handle_nolock(int const fh) throw()
{
[...]
if (CloseHandle(reinterpret_cast<HANDLE>(_get_osfhandle(fh))))
return 0;
[...]
}
fh是一个大于2的值(3,4 ...),因此调试器在从_get_osfhandle访问NULL指针时抛出异常。
为什么这次清理会崩溃?如何检测我是否创建流然后优雅地关闭?这是VS2015的错误吗? (因为在vs2012中没有发生,并且只在连接调试器时崩溃)。
该源已在vs2015的其他电脑上测试过。
修改 我发现了潜在的问题。对于某些操作,使用CreateFile打开文件,我得到文件流的HANDLE。另外,为了在其他操作中使用打开的文件(例如使用jpg库解析它),使用_open_osfhandle重新打开文件
int fd = _open_osfhandle((intptr_t)filehandle, _O_RDONLY);
FILE* fp = _fdopen(fd, "rb");
然后,当程序退出时,清理例程为_open_osfhandle创建的所有文件句柄调用_close,但是,句柄已经使用_close(fd)关闭了;在我的清理程序中。无论哪种方式,系统都会尝试在退出时重新关闭相同的句柄标识符,这会抛出断言(现在是断言而不是崩溃)。
致电_close的公寓,我该怎么做才能告诉O.S.该文件已经关闭,没有必要崩溃吗?
如果我删除了我的清理例程,则断言会按预期消失。