【发布时间】:2016-01-14 15:33:40
【问题描述】:
我正在将一些代码从 VS2010(使用 boost 1.55)迁移到 VS 2015(使用 boost 1.60)。
我最终得到“Microsoft Visual C++ 运行时库”报告 abort() has been called 而 boost rties 抛出异常。但是,我可以让它毫无问题地抛出其他异常(它曾经与 VS2010/boost1.55 一起使用):
#include <boost/filesystem.hpp>
#include <boost/filesystem/operations.hpp>
#include <iostream>
int main( int argc, char* argv[] )
{
// Stepping to folder:
try
{
boost::filesystem::current_path("B:/dev/msvc2015/vobs_bci/public/tst/base/cppunit/utlfile");
std::cout << "Worked" << std::endl; // works OK
}
catch (...)
{
}
// test throwing upon copy_directory because dource folder does not exist:
try
{
boost::filesystem::copy_directory("s", "b");
}
catch (...)
{
std::cout << "Caught" << std::endl; // works OK
}
// test throwing upon copy because target file already exists:
try
{
boost::filesystem::copy("./test.h", "./copied.cpp"); // works
boost::filesystem::copy("./test.h", "./copied.cpp"); // should throw and be caught
}
catch (...)
{
std::cout << "Caught" << std::endl; // never reached...
}
std::cout << "Done" << std::endl;
return 0;
}
这个输出:
Worked
Caught
-> then aborts!
使用调试器,我看到当下面的错误函数(在 filesystem/src/operations.cpp 中)调用 BOOST_FILESYSTEM_THROW 时调用了 abort:
bool error(err_t error_num, const path& p1, const path& p2, error_code* ec,
const char* message)
{
if (!error_num)
{
if (ec != 0) ec->clear();
}
else
{ // error
if (ec == 0)
BOOST_FILESYSTEM_THROW(filesystem_error(message,
p1, p2, error_code(error_num, system_category()))); // << Here!
else
ec->assign(error_num, system_category());
}
return error_num != 0;
}
我检查了调试器,我到达了filesystem_error 构造函数,并且可以毫无问题地退出它,下一步(在调试器中按 F11,现在应该调用 throw),调用 abort()。
奇怪的是,当copy_directory 抛出异常时,它也可以工作,并且这确实调用了与filesystem/src/operations.cpp 完全相同的error 函数。
中止时的调用堆栈是:
> ntdll.dll!KiUserExceptionDispatcher() Inconnu
KernelBase.dll!RaiseException() Inconnu
vcruntime140d.dll!_CxxThrowException(void * pExceptionObject=0x000000000019f670, const _s__ThrowInfo * pThrowInfo=0x000000013fd01870) Ligne 136 C++
test_3rdparty_inprg_boost.exe!`anonymous namespace'::error(unsigned long error_num=80, const boost::filesystem::path & p1={...}, const boost::filesystem::path & p2={...}, boost::system::error_code * ec=0x0000000000000000, const char * message=0x000000013fcf6fb8) Ligne 321 C++
test_3rdparty_inprg_boost.exe!boost::filesystem::detail::copy_file(const boost::filesystem::path & from={...}, const boost::filesystem::path & to={...}, boost::filesystem::detail::copy_option option=none, boost::system::error_code * ec=0x0000000000000000) Ligne 919 C++
test_3rdparty_inprg_boost.exe!boost::filesystem::copy_file(const boost::filesystem::path & from={...}, const boost::filesystem::path & to={...}, boost::filesystem::copy_option option=none, boost::system::error_code & ec) Ligne 550 C++
test_3rdparty_inprg_boost.exe!boost::filesystem::detail::copy(const boost::filesystem::path & from={...}, const boost::filesystem::path & to={...}, boost::system::error_code * ec=0x0000000000000000) Ligne 894 C++
test_3rdparty_inprg_boost.exe!boost::filesystem::copy(const boost::filesystem::path & from={...}, const boost::filesystem::path & to={...}) Ligne 524 C++
test_3rdparty_inprg_boost.exe!main(int argc=1, char * * argv=0x00000000003f3cc0) Ligne 35 C++
test_3rdparty_inprg_boost.exe!invoke_main() Ligne 75 C++
但是我看不到ntdll.dll!KiUserExceptionDispatcher()也看不到KernelBase.dll!RaiseException()的源代码。
【问题讨论】:
-
abort()引发一个导致异常终止的信号 (SIGABRT),而不是异常。catch语句包含异常,而不是信号。这意味着遇到了一个错误,并且在异常启动之前调用了abort。 -
@mikedu95 我看到的问题不是为什么
abort()不能被抓到,而是为什么(也许在哪里)abort()被调用。 -
@mikedu95 但是当我在“Microsft Visual C++ 运行时库”弹出窗口上单击“重试”时,它会将我带到
BOOST_FILESYSTEM_THROW行。为什么这会中止而不是抛出呢? -
@hvd 你说得对,我已经更新了我的评论
-
除了编译器错误之外,唯一想到的是非工作调用堆栈中的某些函数无意中声明为 noexcept,或者更不可能使用不兼容的异常规范声明。
标签: c++ exception-handling visual-studio-2015 boost-filesystem