我现在正在使用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) 构建。将发生以下崩溃: