【发布时间】:2012-09-05 10:16:05
【问题描述】:
我现在使用Boost Unit Test 为我的项目执行单元测试。每次运行单元测试时,都会遇到内存堆栈问题。我调试BOOST库的源代码,发现问题来自于在unit_test_suite.hpp文件中调用以下代码:
void
traverse_test_tree( test_unit_id id, test_tree_visitor& V )
{
global_i = global_i + 1;
std::cout<<global_i<<std::endl;
if( ut_detail::test_id_2_unit_type( id ) == tut_case )
traverse_test_tree( framework::get<test_case>( id ), V );
else
traverse_test_tree( framework::get<test_suite>( id ), V );
}
我从VC10得到的错误信息是:
Unhandled exception at 0x779815de in TestApplication.exe: 0xC00000FD: Stack overflow.
我想知道测试程序有什么问题。谢谢!
编辑根据我查看代码的建议,发生了非常奇怪的事情:如果测试套件与 main() 在同一个程序中定义,它可以工作;但是,如果测试套件来自 .dll,则会发生错误。我列出以下代码来说明我的问题:
boost::unit_test::test_suite* main_global_test_suite;
void Hellotestdll()
{
int i= 1;
int j= 2;
BOOST_CHECK(i == j);
}
boost::unit_test::test_suite* get_abc_test_suite()
{
test_suite* ts = BOOST_TEST_SUITE( "unit_geometric" );
ts->add( BOOST_TEST_CASE( &Hellotestdll ) );
return ts;
}
int main( int argc, char* argv[] )
{
try
{
/**
* Step 1. obtain options
*/
char* optionLine[1024];
int len;
len = obtain_options(optionLine, argc, argv);
/**
* Step 2. perform unit test based on user's options
*/
int test_status=0;
main_global_test_suite = get_abc_test_suite();
test_status = unit_test_main(run_global_test_suite, len, optionLine);
return test_status;
}
catch(std::exception& e)
{
std::cout << e.what() << std::endl;
return 1;
}
catch (const std::string& s)
{
std::cout << s << std::endl;
return 1;
}
catch (...)
{
return 1;
}
}
以上代码运行良好。但如果测试套件来自 .dll,例如:
// dll_header.h
namespace abc
{
ABC_EXPORT boost::unit_test::test_suite* get_geometric_test_suite();
}
// dll_header.cpp
namespace abc
{
using namespace boost;
using namespace boost::unit_test;
void Hellotestdllabc()
{
int i= 1;
int j= 2;
BOOST_CHECK(i == j);
}
boost::unit_test::test_suite* get_abc_test_suite()
{
test_suite* ts = BOOST_TEST_SUITE( "unit_abc" );
ts->add( BOOST_TEST_CASE( &Hellotestdllabc ) );
return ts;
}
}
然后,如果我使用以下代码调用此测试套件:
int main( int argc, char* argv[] )
{
............
/**
* Step 2. perform unit test based on user's options
*/
int test_status=0;
main_global_test_suite = abc::get_abc_test_suite();
test_status = unit_test_main(run_global_test_suite, len, optionLine);
return test_status;
}
会发生烦人的堆栈溢出错误。
问题总结
(1) boost dll with MDd (Succeed)
如果我将 boost 单元测试库(定义为 -DBOOST_ALL_DYN_LINK -DBOOST_TEST_NO_MAIN -DBOOST_TEST_DYN_LINK -DBOOST_ALL_NO_LIB)和正在运行的可执行程序与同一个动态运行时库(多线程调试 Dll (MDd))链接,它将起作用。
(2) boost dll with MTd (Failed)
如果boost单元测试库(定义为-DBOOST_ALL_DYN_LINK -DBOOST_TEST_NO_MAIN -DBOOST_TEST_DYN_LINK -DBOOST_ALL_NO_LIB)和正在运行的可执行程序编译并链接到同一个静态运行时库(Multi-thred Debu (MTd)),我会崩溃,但这次崩溃与我上面报道的不同:
(3) boost static lib with MDd (Failed)
如果 boost 构建为静态库(定义为 -DBOOST_TEST_NO_MAIN -DBOOST_ALL_NO_LIB),并且 boost 库和可执行程序都使用相同的动态运行时库 (MDd) 构建。将发生以下崩溃:
(4) boost static lib with MTd (Failed)
如果 boost 构建为静态库(定义为 -DBOOST_TEST_NO_MAIN -DBOOST_ALL_NO_LIB),并且 boost 库和可执行程序都使用相同的静态运行时库 (MTd) 构建。将发生以下崩溃:
【问题讨论】:
-
什么版本的boost?对于发布版本,我宁愿说是你的代码问题,也许你误解了什么
-
99% 的时间你认为库有问题,问题真的是在你自己的代码中。
-
@Geoffroy 我现在使用 BOOST 1.50.0,最新版本
-
你能展示一些导致堆栈溢出的测试用例的代码吗?检查调用堆栈以查看它是哪个测试用例。
-
@feelfree 最新版本是 1.51.0 :) 不过没关系^^
标签: c++ visual-studio-2010 boost-test