2011-07-17 17 views
12

का पता नहीं लगाता मेरा प्रोग्राम विभाजन त्रुटियों में जाता है, और मुझे कारण नहीं मिल रहा है। सबसे बुरा हिस्सा यह है कि प्रश्न में कार्य हमेशा सेगफॉल्ट नहीं होता है।malloc_consolidate (malloc.c) में सेगमेंटेशन गलती है कि valgrind

GDB बग की पुष्टि करता है और इस पश्व-अनुरेखन पैदावार:

Program received signal SIGSEGV, Segmentation fault. 
0xb7da6d6e in malloc_consolidate (av=<value optimized out>) at malloc.c:5169 
5169 malloc.c: No such file or directory. 
    in malloc.c 
(gdb) bt 
#0 0xb7da6d6e in malloc_consolidate (av=<value optimized out>) at malloc.c:5169 
#1 0xb7da9035 in _int_malloc (av=<value optimized out>, bytes=<value optimized out>) at malloc.c:4373 
#2 0xb7dab4ac in __libc_malloc (bytes=525) at malloc.c:3660 
#3 0xb7f8dc15 in operator new(unsigned int)() from /usr/lib/i386-linux-gnu/libstdc++.so.6 
#4 0xb7f72db5 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&)() 
    from /usr/lib/i386-linux-gnu/libstdc++.so.6 
#5 0xb7f740bf in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_M_clone(std::allocator<char> const&, unsigned int)() 
    from /usr/lib/i386-linux-gnu/libstdc++.so.6 
#6 0xb7f741f1 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::reserve(unsigned int)() from /usr/lib/i386-linux-gnu/libstdc++.so.6 
#7 0xb7f6bfec in std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow(int)() from /usr/lib/i386-linux-gnu/libstdc++.so.6 
#8 0xb7f70e1c in std::basic_streambuf<char, std::char_traits<char> >::xsputn(char const*, int)() from /usr/lib/i386-linux-gnu/libstdc++.so.6 
#9 0xb7f5b498 in std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<unsigned long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, unsigned long) const() from /usr/lib/i386-linux-gnu/libstdc++.so.6 
#10 0xb7f5b753 in std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, unsigned long) const() from /usr/lib/i386-linux-gnu/libstdc++.so.6 
#11 0xb7f676ac in std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<unsigned long>(unsigned long)() 
    from /usr/lib/i386-linux-gnu/libstdc++.so.6 
#12 0xb7f67833 in std::basic_ostream<char, std::char_traits<char> >::operator<<(unsigned int)() from /usr/lib/i386-linux-gnu/libstdc++.so.6 
#13 0x08049c42 in sim::Address::GetS (this=0xbfffec40) at address.cc:27 
#14 0x0806a499 in sim::UserGenerator::ProcessEvent (this=0x80a1af0, e=...) at user-generator.cc:59 
#15 0x0806694b in sim::Simulator::CommunicateEvent (this=0x809f970, e=...) at simulator.cc:144 
#16 0x0806685d in sim::Simulator::ProcessNextEvent (this=0x809f970) at simulator.cc:133 
#17 0x08065d76 in sim::Simulator::Run (seed=0) at simulator.cc:53 
#18 0x0807ce85 in main (argc=1, argv=0xbffff454) at main.cc:75 
(gdb) f 13 
#13 0x08049c42 in sim::Address::GetS (this=0xbfffec40) at address.cc:27 
27 oss << m_address; 
(gdb) p this->m_address 
$1 = 1 

विधि वर्ग पता GetS एक नंबर (uint32_t m_address) एक स्ट्रिंग में तब्दील हो और यह देता है। के रूप में पश्व-अनुरेखन में देखा जा सकता, m_address ठीक से परिभाषित किया गया है,

std::string 
Address::GetS() const 
{ 
    std::ostringstream oss; 
    oss << m_address; 
    return oss.str(); 
} 

इसके अलावा: कोड (बहुत सरल) निम्नलिखित है।

अब, मैंने valgrind का उपयोग करके अपना प्रोग्राम चलाने की कोशिश की है। प्रोग्राम इस तथ्य के कारण क्रैश नहीं होता है कि वाल्ग्रिंड malloc() को अन्य कार्यों के बीच बदल देता है।

LEAK SUMMARY: 
    definitely lost: 0 bytes in 0 blocks 
    indirectly lost: 0 bytes in 0 blocks 
    possibly lost: 4,367 bytes in 196 blocks 
    still reachable: 9,160 bytes in 198 blocks 
     suppressed: 0 bytes in 0 blocks 

सभी possibly lost इस तरह बैकट्रैस को देखें:

80 bytes in 5 blocks are possibly lost in loss record 3 of 26 
    at 0x4024B64: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
    by 0x40DBDB4: std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16) 
    by 0x40DE077: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16) 
    by 0x40DE1E5: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16) 
    by 0x806AF62: sim::UserGenerator::CreateUser(unsigned int) (user-generator.cc:152) 

मुझे नहीं लगता कि इस बग से संबंधित है

त्रुटि सारांश कोई स्मृति लीक को दर्शाता है। हालांकि, प्रश्न में कोड following this link पाया जा सकता है।

मैं libstdc++ में एक बग के बारे में सोच रहा हूं। हालांकि, यह कितनी संभावना होगी? मैंने इस तरह की लाइब्रेरी को अपग्रेड किया है। वर्तमान में मेरे सिस्टम पर स्थापित संस्करण हैं।

$ dpkg -l | grep libstdc 
ii libstdc++5   1:3.3.6-23 The GNU Standard C++ Library v3 
ii libstdc++6   4.6.1-1  GNU Standard C++ Library v3 
ii libstdc++6-4.1-dev 4.1.2-27 The GNU Standard C++ Library v3 (development files) 
ii libstdc++6-4.3-dev 4.3.5-4  The GNU Standard C++ Library v3 (development files) 
ii libstdc++6-4.4-dev 4.4.6-6  GNU Standard C++ Library v3 (development files) 
ii libstdc++6-4.5-dev 4.5.3-3  The GNU Standard C++ Library v3 (development files) 
ii libstdc++6-4.6-dev 4.6.1-1  GNU Standard C++ Library v3 (development files) 

अब बात यह है कि मुझे यकीन है कि कौन-सा संस्करण g++ का उपयोग करता है नहीं कर रहा हूँ, और वहाँ एक विशेष संस्करण के उपयोग को लागू करने के कुछ साधन है या नहीं।

मैं क्या सोच रहा हूं GetS को संशोधित करना है। लेकिन यह एकमात्र तरीका है जिसे मैं जानता हूं। क्या आप कोई विकल्प सुझाते हैं?

आखिरकार, मैं std::string को सरल char* के साथ बदलने पर भी विचार कर रहा हूं। शायद थोड़ा कठोर, लेकिन मैं इसे अलग नहीं रखूंगा।

योग्यता में कोई विचार?

सभी को अग्रिम धन्यवाद।

बेस्ट, Jir

+4

सबसे पहले, मैं आपको सलाह देता हूं कि आप 'MALLOC_CHECK_' पर्यावरण चर सेट 3 के साथ चलने का प्रयास करें, जो आपके प्रबंधन संरचनाओं के कुछ हिस्सों को ओवरराउन करने के लिए जल्दी ही' malloc' निरस्त कर सकता है, जबकि किसी भी तरह से इस बारे में अनजान बनाते हैं । मैं यह भी सुझाव दूंगा कि आप देखेंगे कि क्या आपके पास कोई वाल्ग्रिंड सुपरप्रेसन विकल्प है जो – Hasturkun

+2

समस्या को छुपा रहा है। मैंने आपके कोड की त्वरित समीक्षा की है: निम्नलिखित वर्ग 'तीन नियम' का पालन नहीं करते हैं: 'बेसस्टेशन', 'मोबाइल टर्मिनल' , 'नेटवर्क',' सिम्युलेटर ',' उपयोगकर्ता जेनरेटर 'यह डबल डिलीट के कारण मेमोरी कूपशन का कारण हो सकता है। –

+0

@ हस्तार्कुन: कोशिश करेंगे और इसे जांचेंगे। उपयोगी टिप! @ मार्टिन: टिप्पणी के लिए धन्यवाद! मैं उन हिस्सों की समीक्षा करूंगा। – Jir

उत्तर

24

ठीक है। यह नहीं है समस्या:

मैं

libstdc में एक बग की सोच रहा हूँ ++ समस्या यह है कि आप कुछ स्मृति बफर अधिलेखित कर दिया और स्मृति प्रबंधक द्वारा इस्तेमाल किया संरचनाओं में से एक दूषित है। कठिन हिस्सा इसे ढूंढने जा रहा है। वाल्ग्रिंड आपको स्मृति के आवंटित टुकड़े के अंत में लिखने के बारे में जानकारी नहीं देता है।

ऐसा मत करो:

आखिरकार, मैं भी सरल चार के साथ std :: स्ट्रिंग को बदलने के लिए विचार कर रहा हूँ *। शायद थोड़ा कठोर, लेकिन मैं इसे अलग नहीं रखूंगा।

आपके पास पहले से ही स्मृति प्रबंधन के साथ पर्याप्त समस्याएं हैं। यह सिर्फ और समस्याएं जोड़ देगा। Std :: string या मेमोरी प्रबंधन दिनचर्या के साथ बिल्कुल कुछ नहीं गलत है। उनका भारी परीक्षण और उपयोग किया जाता है। अगर दुनिया भर में कुछ गलत लोग चिल्लाना शुरू कर देंगे (यह बड़ी खबर होगी)।

http://mercurial.intuxication.org/hg/lte_sim/file/c2ef6e0b6d41/src/ पर अपना कोड पढ़ना ऐसा लगता है कि आप अभी भी writting कोड (C with Classes) की सी शैली में फंस गए हैं। तो आपके पास स्वचालित करने के लिए सी ++ की शक्ति है (आपके कोड को उड़ाना) लेकिन अभी भी सी

से संबंधित सभी समस्याएं हैं, आपको स्वामित्व के संदर्भ में अपना कोड फिर से देखना होगा। आप चीजों को पॉइंटर तरीके से बहुत पास करते हैं। नतीजतन पॉइंटर के स्वामित्व का पालन करना मुश्किल है (और इस प्रकार इसे हटाने के लिए जिम्मेदार कौन है)।

मुझे लगता है कि बग खोजने में आपको सबसे अच्छा शर्त है कि प्रत्येक वर्ग के लिए यूनिट परीक्षण लिखना है। फिर वैल-पीस के माध्यम से यूनिट परीक्षण चलाएं। मुझे यह एक दर्द पता है (लेकिन अब आप इसे शुरू करने के लिए किया जाना चाहिए था कि आप सभी को दर्द हो रहा है)।

+0

मुझे कैसे पता चलेगा कि मुझे नहीं पता कि क्या मुझे नहीं पता कि यह अस्तित्व में है? :) एक तरफ मजाक कर, संकेतों के लिए धन्यवाद। इस तरह की टिप्पणियों के लिए धन्यवाद कि मैं कुछ और सीख सकता हूं। मैं इस पर गौर करूंगा। धन्यवाद! – Jir

संबंधित मुद्दे