throwing an exception causes segmentation fault
Collection CollectionFactory::createFromMap(const std::string& name,
const DataMap& dm) const
{
if (!Collection::isNameValid(name))
{
const std::string error = "invalid collection name";
throw std::invalid_argument(error);
}
Collection c(name, dm);
dm.initDataCollection(&c, true);
return c;
}
Whenever the throw statement is executed, I'm getting a segmentation fault. Here is the cause from Valgrind output. I've no idea what's going on.
==21124== Invalid read of size 1
==21124== at 0x41D2190: parse_lsda_header(_Unwind_Context*, unsigned char const*, lsda_header_info*) (eh_personality.cc:62)
==21124== by 0x41D24A9: __gxx_personality_v0 (eh_personality.cc:228)
==21124== by 0x4200220: _Unwind_RaiseException (unwind.inc:109)
==21124== by 0x41D2C9C: __cxa_throw (eh_throw.cc:75)
==21124== by 0x4079BFB: corestore::CollectionFactory::createFromMap(std::string const&, corestore::DataMap const&) const (CollectionFactory.C:43)
==21124== by 0x8188F86: CollectionFactoryTest::testCreateNewFromMap_InvalidName() (CollectionFactoryTest.C:91)
==21124== by 0x81895D3: CppUnit::TestCaller<CollectionFactoryTest>::runTest() (TestCaller.h:166)
==21124== by 0x40D1BB5: CppUnit::TestCaseMethodFunctor::operator()() const (TestCase.cpp:34)
==21124== by 0x40C18E3: CppUnit::DefaultProtector::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (DefaultProtector.cpp:15)
==21124== by 0x40CD0FC: CppUnit::ProtectorChain::ProtectFunctor::operator()() const (ProtectorChain.cpp:20)
==21124== by 0x40CCA65: CppUnit::ProtectorChain::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (ProtectorChain.cpp:77)
==21124== by 0x40DC6C4: CppUnit::TestResult::protect(CppUnit::Functor const&, CppUnit::Test*, std::string const&) (TestResult.cpp:178)
==21124== Address 0xc82f is not stack'd, malloc'd or (recently) free'd
I've had several iterations of the unit test that's bombing, but here is the current one that exhibits the same bug as all the others:
void CollectionFactoryTest::testCreateNewFromMap_InvalidName()
{
const char* MAP_FILE =
"smallMapWithThreeSets.xml";
const char* NAME1 = "name/invalidname";
const char* NAME2 = "name/invalidname";
DataMapReader dmr;
DataMap dm = dmr.getDataMapFromFile(MAP_FILE);
CollectionFactory cf;
try
{
cf.createFromMap(NAME1, dm);
}
catch (std::exception const& e)
{
std::cerr << e.what() << std::endl;
}
/*CPPUNIT_ASSERT_THROW(cf.createFromMap(NAME1, dm), std::invalid_argument);
CPPUNIT_ASSERT_THROW(cf.createFromMap(NAME2, dm), std::invalid_argument);*/
}
Per request, the contents of isNameValid:
bool Collection::isNameValid(const std::string& name)
{
/* can't be blank */
if(name.length() == 0)
{
return false;
}
/* Can't contain '/' */
if(name.find('/') != std::string::npos)
{
return false;
}
return true;
}
Is that the very first Valgrind error or are there previous ones?
My guess is that there are previous ones and one of those is corrupting memory and causing throw to break.
Dave, there is missing code in your execution path, which prevents from nailing down the problem:
I'd recommend trying stripping down the testcase as much as possible while the segmentation fault is still reproducible.
I have the following guesses for the problem:
Though this isn't related to the segmentation fault mentioned in the question, the same potential problems can apply to the code below throwing exception in the CollectionFactory::createFromMap():
How are you linking the code? If you're creating a shared library for instance, it's possible that you need to specify compilation flags for position-independent code, such as -fPIC (gcc/g++).
链接地址: http://www.djcxy.com/p/44800.html上一篇: Iphone如何知道蓝牙耳机是否连接
下一篇: 抛出异常会导致分段错误