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

जब भी फेंक कथन निष्पादित किया जाता है, तो मुझे सेगमेंटेशन गलती मिल रही है। Valgrind आउटपुट का कारण यहां दिया गया है। मुझे नहीं पता कि क्या हो रहा है।अपवाद फेंकने सेगमेंटेशन गलती

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);*/ 
} 

अनुरोध के अनुसार, isNameValid की सामग्री:

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

मैं इकाई परीक्षण बम विस्फोट है, लेकिन यहां इस बात का कई पुनरावृत्तियों लिया है वर्तमान एक है कि सभी दूसरों के रूप में ही बग दर्शाती है :

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

क्या यह पहली बार वालग्रिंड त्रुटि है या पिछले कोई हैं?

मेरा अनुमान है कि पिछले लोग हैं और उनमें से एक स्मृति को दूषित कर रहा है और फेंकने का कारण बन रहा है।

+0

सभी पिछली त्रुटियों में सिस्टम कॉल (सिग्नेशन, लिखना) या अनियमित मूल्यों पर सशर्त कूद में अनियमित मूल्य शामिल हैं, इसलिए ये स्मृति को दूषित नहीं कर रहे हैं। – Dave

+0

क्या आप समस्या को कम कर सकते हैं? यदि आप केवल testCreateNewFromMap_InvalidName चलाते हैं तो क्या आपको अभी भी segfault मिलता है? –

+0

मैंने एक अलग कार्यक्रम बनाया। यह सिर्फ मुख्य है। यह सब करता है कि उस परीक्षा में क्या था। वही विभाजन त्रुटि होती है। मैंने एक अलग कार्यक्रम भी बनाया जो सिर्फ अपवाद फेंकता है (मेरी लाइब्रेरी का उपयोग नहीं करता है), और यह काम करता है। इसके अलावा, अगर मुझे पकड़ नहीं है, तो मुझे "निरस्त" के प्रिंट आउट के साथ एक साफ निकास मिलता है। – Dave

1

आप कोड को कैसे लिंक कर रहे हैं? उदाहरण के लिए यदि आप साझा लाइब्रेरी बना रहे हैं, तो यह संभव है कि आपको स्थिति-स्वतंत्र कोड, जैसे -fPIC (gcc/g ++) के लिए संकलन झंडे निर्दिष्ट करने की आवश्यकता हो।

+0

साझा लाइब्रेरी में अपवादों को फेंक दिया जा रहा है। दरअसल, जब मैं स्थैतिक रूप से लिंक करता हूं, तो बग दूर हो जाती है। हालांकि, काम पर, हमारे पास दो ओएस कॉन्फ़िगरेशन हैं। नई 64-बिट प्रणाली पुराने 9.1 के बजाय 11.1 इंटेल कंपाइलर का उपयोग करती है। यह 3.3 के बजाय जीसीसी 4 + का भी उपयोग करता है, और यह नई प्रणाली पर काम कर रहा है। मैं इंटेल के साथ काम करने का इंतजार कर रहा हूं यह देखने के लिए कि क्या यह 9.1 कंपाइलर के साथ एक ज्ञात मुद्दा है। – Dave

2

डेव, आपकी निष्पादन पथ है, जो समस्या को व्यवस्थित करना करने से रोकता है में कोड याद आ रही है:

  • DataMapReader निर्माता;
  • DataMapReader का कार्यान्वयन :: getDataMapFromFile();
  • डेटामैप कन्स्ट्रक्टर;
  • संग्रह फैक्टरी कन्स्ट्रक्टर;

मैं जितना संभव हो सके टेस्टकेस को अलग करने की कोशिश करने की सिफारिश करता हूं, जबकि सेगमेंटेशन गलती अभी भी पुन: उत्पन्न होती है।

मैं इस समस्या के लिए निम्न अनुमान है:

  • DataMapReader :: getDataMapFromFile() std के लिए एक संदर्भ :: स्ट्रिंग को स्वीकार करता है और उसके बाद दुकानों यह या तो स्थिर स्मृति में या DataMapReader उदाहरण में या DataMap उदाहरण में। यह अपरिभाषित व्यवहार की ओर जाता है, क्योंकि संदर्भित std :: स्ट्रिंग ऑब्जेक्ट को DataMapReader :: getDataMapFromFile() से बाहर निकलने के तुरंत बाद नष्ट कर दिया जाएगा, इसलिए सभी शेष संदर्भ स्वचालित रूप से अमान्य हो जाते हैं।
  • DataMapReader :: getDataMapFromFile() एक स्टैक पर संग्रहीत डेटामैप उदाहरण का संदर्भ देता है। जैसे ही DataMapReader :: getDataMapFromFile() रिटर्न और डीएम के लिए प्रतिलिपि बनाने से पहले इस तरह का एक उदाहरण नष्ट हो जाएगा, जो अपरिभाषित व्यवहार की ओर जाता है। यह मामला असंभव है, क्योंकि कंपाइलर आमतौर पर स्टैक पर संग्रहीत ऑब्जेक्ट्स को लौटने वाले पॉइंटर्स या संदर्भों के बारे में चेतावनी देते हैं।
  • यदि डेटामैप रीडर :: getMapFromFile() मूल्य से डेटामैप लौटाता है और डेटामैप में स्पष्ट रूप से परिभाषित कॉपी कन्स्ट्रक्टर और/या कॉपी असाइनमेंट ऑपरेटर नहीं है, या इसमें उन कन्स्ट्रक्टर और/या ऑपरेटर के लिए गलत कार्यान्वयन हैं, जो अनुचित रूप से पॉइंटर्स की प्रतिलिपि को संभालते हैं और/या डेटामैप के स्वामित्व वाले सदस्यों के संदर्भ (या मूल्य द्वारा संग्रहीत अन्य सदस्यों को वही समस्या दोबारा मिलती है)। इस मामले में संदर्भित सदस्यों को DataMapReader :: getMapFromFile() से लौटने से पहले एक स्टैक पर संग्रहीत उदाहरण के लिए डेटामैप विनाशक में नष्ट किया जा सकता है, जो अपरिभाषित व्यवहार की ओर जाता है।

हालांकि इस विभाजन गलती प्रश्न में आपका उल्लेख से संबंधित नहीं है, एक ही संभावित समस्याओं CollectionFactory में अपवाद फेंक नीचे दिया गया कोड लागू कर सकते हैं :: createFromMap():

  • संग्रह निर्माता इनपुट पैरामीटर (std :: स्ट्रिंग और डेटामैप) के संदर्भों को संग्रहीत नहीं करना चाहिए यदि उनका जीवनकाल संग्रह उदाहरण के जीवनकाल से कम है।
  • DataMap.initDataCollection() को संग्रह उदाहरण में पॉइंटर स्टोर नहीं करना चाहिए, क्योंकि स्टैक पर बनाए गए संग्रह उदाहरण का जीवनकाल डेटामैप उदाहरण के जीवनकाल से कम है। संग्रह फ़ैक्टरी :: createFromMap() से लौटने से पहले संग्रह उदाहरण नष्ट हो जाएगा।
  • संग्रह को कॉपी कन्स्ट्रक्टर और/या असाइनमेंट ऑपरेटर की प्रतिलिपि लागू करनी चाहिए, अन्यथा यह ऊपर उल्लिखित समस्या से ग्रस्त होगा।
संबंधित मुद्दे