2010-02-09 5 views
7
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; 
} 

Всякий раз, когда выполняется инструкция throw, я получаю ошибку сегментации. Вот причина выхода Valgrind. Я понятия не имею, что происходит.отбрасывание исключения вызывает ошибку сегментации

==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 

У меня было несколько итераций модульного тестирования, что это взрыв, но вот ток один, который имеет ту же ошибку, как и все остальные:

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 запроса, содержание 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; 
} 

ответ

1

Это первая ошибка Valgrind или есть предыдущие?

Я предполагаю, что есть предыдущие, и один из них развращает память и вызывает бросок.

+0

Все предыдущие ошибки включают либо неинициализированные значения в системных вызовах (sigaction, write), либо условный переход на неинициализированные значения, поэтому они не повреждают память. – Dave

+0

Можете ли вы уменьшить проблему? Если вы запускаете testCreateNewFromMap_InvalidName, вы все равно получаете segfault? –

+0

Я создал отдельную программу. Это просто главное. Все, что он делает, это то, что было в этом тесте. Произошла такая же ошибка сегментации. Я также создал отдельную программу, которая просто генерирует исключение (не использует мою библиотеку), и она работает. Кроме того, если я не поймаю, я получаю чистый выход с печатью из «Aborted». – Dave

1

Как вы связываете код? Например, если вы создаете общую библиотеку, возможно, вам нужно указать флаги компиляции для независимого от позиции кода, например -fPIC (gcc/g ++).

+0

Исключения составляют общую библиотеку. Действительно, когда я связываю статически, ошибка исчезает. Однако на работе у нас есть две конфигурации ОС. Новая 64-разрядная система использует 11.1 Intel Compiler вместо старого 9.1. Он также использует gcc4 + вместо 3.3, и он работает над новой системой. Я жду, чтобы работать с Intel, чтобы убедиться, что это известная проблема с компилятором 9.1. – Dave

2

Дэйв, там отсутствует код на вашем пути выполнения, который предотвращает от гвоздей вниз проблему:

  • DataMapReader конструктор;
  • реализация DataMapReader :: getDataMapFromFile();
  • Конструктор DataMap;
  • CollectionFactory constructor;

Я бы рекомендовал как можно больше удалять тестовую пробку, пока ошибка сегментации все еще воспроизводима.

у меня есть следующие предположения для задачи:

  • DataMapReader :: getDataMapFromFile() принимает ссылку на STD :: строку и затем сохраняет его либо в статической памяти или в DataMapReader, например, или в случае DataMap. Это приводит к неопределенному поведению, поскольку ссылочный объект std :: string будет уничтожен сразу после выхода из DataMapReader :: getDataMapFromFile(), поэтому все остальные ссылки автоматически становятся недействительными.
  • DataMapReader :: getDataMapFromFile() возвращает ссылку на экземпляр DataMap, хранящийся в стеке. Такой экземпляр будет уничтожен, как только DataMapReader :: getDataMapFromFile() вернется и до того, как будет создан конструктор копирования для dm, что приведет к неопределенному поведению. Этот случай маловероятен, поскольку компиляторы обычно предупреждают о возврате указателей или ссылок на объекты, хранящиеся в стеке.
  • Если DataMapReader :: getMapFromFile() возвращает DataMap по значению, а DataMap не имеет явно заданного оператора копирования и/или копирования, или имеет неправильные реализации для этого конструктора и/или оператора, который неправильно обрабатывает копирование указателей и/или ссылки на членов, принадлежащих DataMap (или другие члены, хранящиеся по значению, имеют ту же проблему рекурсивно). В этом случае ссылочные члены могут быть уничтожены в деструкторе DataMap, вызванном экземпляром, хранящимся в стеке, перед возвратом из DataMapReader :: getMapFromFile(), что приводит к неопределенному поведению.

Хотя это не связанно с ошибкой сегментации, упомянутой в вопросе, одни и те же потенциальные проблемы могут обратиться к коду ниже метание исключения в CollectionFactory :: createFromMap():

  • Collection конструктор не следует хранить ссылки на входные параметры (std :: string и DataMap), если их время жизни меньше времени жизни экземпляра Collection.
  • DataMap.initDataCollection() не должен хранить указатель на экземпляр Collection, поскольку время жизни экземпляра Collection, созданного в стеке, меньше времени жизни экземпляра DataMap. Экземпляр коллекции будет уничтожен перед возвратом из CollectionFactory :: createFromMap().
  • Коллекция должна иметь правильно реализованный экземпляр-конструктор и/или оператор присваивания копии, иначе он будет страдать от проблемы, описанной выше.
Смежные вопросы