2012-06-02 12 views
7

कई दिनों से मैं अपने सॉफ़्टवेयर में मेमोरी बग खोजने की कोशिश कर रहा हूं।
यह काफी जटिल है, लेकिन अच्छी तरह से संरचित और स्वरूपित (मेरी राय में)।
बग 64 बिट मशीन पर डेबियन जीएनयू/लिनक्स चल रहा है।
(... मेरी 32 बिट मशीन पर नहीं - शून्य */int mixup?)
यदि आप मेरी मदद कर सकते हैं तो मैं वास्तव में खुश रहूंगा।valgrind | आकार 8 का अमान्य पढ़ने | पता 0x7a41270 आकार 4 के ब्लॉक के अंदर 0 बाइट्स

स्रोत कोड स्निपेट इस संदेश के अंत में अनुसरण करते हैं।
अगर वह पर्याप्त नहीं है, आप के सभी स्रोत चेकआउट कर सकते हैं:
http://savannah.nongnu.org/svn/?group=cybop

इन्सटाल फ़ाइल के निर्देश संकलन और चलाने के लिए का पालन करें।

सॉफ्टवेयर चल रहा है इस प्रकार है ठीक काम करता है:

enter code here ईसाई @ डेनेब:/घर/परियोजना/cybop/उदाहरण $ ../src/controller/cyboi

विकल्प के साथ यह चल रहा है Memcheck त्रुटियों लाता है
ईसाई @ डेनेब:/घर/परियोजना/cybop/उदाहरण $ ../src/controller/cyboi --help

मैं इस कमांड लाइन का उपयोग कर Memcheck हुई:
ईसाई @ डेनेब: valgrind में/घर/परियोजना/साइबॉप/उदाहरण $ valgrind --log-file = memche ck.log --tool = Memcheck --read-वर-जानकारी = हाँ --track-मूल = हाँ ../src/controller/cyboi --help

यहाँ Memcheck उत्पादन होता है:

==20072== Memcheck, a memory error detector 
==20072== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. 
==20072== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info 
==20072== Command: ../src/controller/cyboi --help 
==20072== Parent PID: 18978 
==20072== 
==20072== Invalid read of size 8 
==20072== at 0x40AF0E: decode_utf_8 (utf_8_decoder.c:298) 
==20072== by 0x42A53D: optionalise_argument (argument_optionaliser.c:110) 
==20072== by 0x42A786: optionalise (optionaliser.c:107) 
==20072== by 0x401507: main (cyboi.c:168) 
==20072== Address 0x7a41270 is 0 bytes inside a block of size 4 alloc'd 
==20072== at 0x402894D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==20072== by 0x404C52: allocate_array (array_allocator.c:66) 
==20072== by 0x40A0FC: allocate_item (item_allocator.c:62) 
==20072== by 0x42A4D2: optionalise_argument (argument_optionaliser.c:85) 
==20072== by 0x42A786: optionalise (optionaliser.c:107) 
==20072== by 0x401507: main (cyboi.c:168) 
==20072== 
==20072== Invalid read of size 8 
==20072== at 0x40AF31: decode_utf_8 (utf_8_decoder.c:300) 
==20072== by 0x42A53D: optionalise_argument (argument_optionaliser.c:110) 
==20072== by 0x42A786: optionalise (optionaliser.c:107) 
==20072== by 0x401507: main (cyboi.c:168) 
==20072== Address 0x7a41270 is 0 bytes inside a block of size 4 alloc'd 
==20072== at 0x402894D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==20072== by 0x404C52: allocate_array (array_allocator.c:66) 
==20072== by 0x40A0FC: allocate_item (item_allocator.c:62) 
==20072== by 0x42A4D2: optionalise_argument (argument_optionaliser.c:85) 
==20072== by 0x42A786: optionalise (optionaliser.c:107) 
==20072== by 0x401507: main (cyboi.c:168) 
==20072== 
==20072== 
==20072== HEAP SUMMARY: 
==20072==  in use at exit: 0 bytes in 0 blocks 
==20072== total heap usage: 34 allocs, 34 frees, 8,232 bytes allocated 
==20072== 
==20072== All heap blocks were freed -- no leaks are possible 
==20072== 
==20072== For counts of detected and suppressed errors, rerun with: -v 
==20072== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 4) 

सॉफ्टवेयर चल रहा है इस प्रकार है:
ईसाई @ डेनेब:/घर/परियोजना/cybop/उदाहरण $ ../src/controller/cyboi --knowledge ui_control/run.cybol

... इन त्रुटियों को पैदा करता है:

साइबोई: मालो सीसी: 30 9 6: sYSMALLOc: दावा '(old_top == ((mbinptr) (((char *) & ((av) -> डिब्बे [((1) - 1) * 2])) - __builtin_offsetof (संरचना malloc_chunk, एफडी))) & & old_size == 0) || ((अहस्ताक्षरित लंबे) (old_size)

= (अहस्ताक्षरित लंबे) ((((__ builtin_offsetof (struct malloc_chunk, fd_nextsize)) + ((2 * (sizeof (size_t))) - 1)) & ~ ((2 * (sizeof (size_t))) - 1))) & & ((old_top) -> आकार & 0x1) & & ((अहस्ताक्षरित लंबे) old_end & pagemask) == 0) 'विफल रहा है। निरस्त

किसी भी मदद की वास्तव में सराहना की जाएगी। मुझे वास्तव में अब कौन सी जगह डीबग करने के बारे में पता नहीं है।

स्रोत कोड इस प्रकार है:

// 
// cyboi.c 
// 

// The cybol knowledge file path item. 
void* k = *NULL_POINTER_STATE_CYBOI_MODEL; 

// Allocate cybol knowledge file path item. 
allocate_item((void*) &k, (void*) NUMBER_0_INTEGER_STATE_CYBOI_MODEL, (void*) WIDE_CHARACTER_TEXT_STATE_CYBOI_TYPE); 

// Optionalise command line argument options. 
optionalise((void*) &m, k, (void*) LOG_LEVEL, (void*) LOG_OUTPUT, (void*) p1, (void*) &p0); 

// 
// optionaliser.c 
// 

while (*TRUE_BOOLEAN_STATE_CYBOI_MODEL) { 

    compare_integer_greater_or_equal((void*) &b, (void*) &j, p5); 

    if (b != *FALSE_BOOLEAN_STATE_CYBOI_MODEL) { 

     break; 
    } 

    optionalise_argument(p0, p1, p2, p3, p4, p5, (void*) &j); 

    // Increment loop variable. 
    j++; 
} 

// 
// argument_optionaliser.c 
// 

// The command line argument option as multibyte character array. 
void* od = *NULL_POINTER_STATE_CYBOI_MODEL; 
int oc = *NUMBER_0_INTEGER_STATE_CYBOI_MODEL; 
// The option, value as wide character item. 
void* ow = *NULL_POINTER_STATE_CYBOI_MODEL; 
// The option, value as wide character item data, count. 
void* owd = *NULL_POINTER_STATE_CYBOI_MODEL; 
void* owc = *NULL_POINTER_STATE_CYBOI_MODEL; 

// Allocate option, value wide character item. 
allocate_item((void*) &ow, (void*) NUMBER_0_INTEGER_STATE_CYBOI_MODEL, (void*) WIDE_CHARACTER_TEXT_STATE_CYBOI_TYPE); 

// Get command line argument option. 
// Example: "--loglevel" 
copy_array_forward((void*) &od, p4, (void*) POINTER_STATE_CYBOI_TYPE, (void*) PRIMITIVE_STATE_CYBOI_MODEL_COUNT, (void*) VALUE_PRIMITIVE_STATE_CYBOI_NAME, p6); 

if (od != *NULL_POINTER_STATE_CYBOI_MODEL) { 

    // Get command line argument option count (number of characters). 
    oc = strlen((char*) od); 

    // Decode multibyte character option into wide character. 
    decode_utf_8(ow, od, (void*) &oc); 

} else { 

    log_write((void*) stdout, L"Error: Could not optionalise command line argument. The command line argument option is null.\n"); 
} 

// 
// utf_8_decoder.c 
// 

// The destination item data, count, size. 
void* dd = *NULL_POINTER_STATE_CYBOI_MODEL; 
void* dc = *NULL_POINTER_STATE_CYBOI_MODEL; 
void* ds = *NULL_POINTER_STATE_CYBOI_MODEL; 
// The new destination size. 
int nds = *NUMBER_0_INTEGER_STATE_CYBOI_MODEL; 

// Get destination item count, size. 
copy_array_forward((void*) &dc, p0, (void*) POINTER_STATE_CYBOI_TYPE, (void*) PRIMITIVE_STATE_CYBOI_MODEL_COUNT, (void*) VALUE_PRIMITIVE_STATE_CYBOI_NAME, (void*) COUNT_ITEM_STATE_CYBOI_NAME); 
copy_array_forward((void*) &ds, p0, (void*) POINTER_STATE_CYBOI_TYPE, (void*) PRIMITIVE_STATE_CYBOI_MODEL_COUNT, (void*) VALUE_PRIMITIVE_STATE_CYBOI_NAME, (void*) SIZE_ITEM_STATE_CYBOI_NAME); 

// Initialise new destination size. 
calculate_integer_add((void*) &nds, p2); 

// Reallocate destination item. 
reallocate_item(p0, (void*) &nds, (void*) WIDE_CHARACTER_TEXT_STATE_CYBOI_TYPE); 

// Set locale. 
// CAUTION! This setting IS NECESSARY for UTF-8 character conversion 
// with restartable multibyte conversion functions like "mbsnrtowcs" 
// and "wcsnrtombs" to work correctly. 
// The return value is not used; this is a global setting. 
char* loc = setlocale(LC_CTYPE, ""); 

// Get destination item data. 
copy_array_forward((void*) &dd, p0, (void*) POINTER_STATE_CYBOI_TYPE, (void*) PRIMITIVE_STATE_CYBOI_MODEL_COUNT, (void*) VALUE_PRIMITIVE_STATE_CYBOI_NAME, (void*) DATA_ITEM_STATE_CYBOI_NAME); 

// Initialise error number. 
// It is a global variable/ function and other operations 
// may have set some value that is not wanted here. 
// 
// CAUTION! Initialise the error number BEFORE calling the function 
// that might cause an error. 
errno = *NUMBER_0_INTEGER_STATE_CYBOI_MODEL; 

// Converts the multibyte character string into a wide character string. 
// Returns the number of wide characters 
// successfully converted, except in the case of an encoding error. 
// 
// CAUTION! The multibyte source character string does NOT need to be 
// null-terminated, since the third parametre already indicates its count. 
// 
// CAUTION! Hand over the NEW destination size as fourth parametre, 
// since it indicates the maximum number of characters to be converted 
// and conversion would break too early if that parametre was too small. 
// 
// CAUTION! The fifth parametre may be NULL. In this case, a static 
// anonymous state only known to the function internally is used instead. 
// It just indicates where conversion is started. 
int n = mbsnrtowcs((wchar_t*) dd, (const char**) &sd, *((size_t*) sc), *((size_t*) ds), (mbstate_t*) *NULL_POINTER_STATE_CYBOI_MODEL); 

if (n >= *NUMBER_0_INTEGER_STATE_CYBOI_MODEL) { 

    // Set destination count to the number of WIDE characters converted. 
    copy_integer(dc, (void*) &n); 

} else { 

    if (errno == EILSEQ) { 

     fwprintf(stdout, L"TEST ERROR EILSEQ errno: %i\n", errno); 
     log_message_terminated((void*) ERROR_LEVEL_LOG_CYBOI_MODEL, (void*) L"Could not decode utf-8. The input string contains an invalid multibyte sequence."); 

    } else { 

     fwprintf(stdout, L"TEST ERROR UNKNOWN errno: %i\n", errno); 
     log_message_terminated((void*) ERROR_LEVEL_LOG_CYBOI_MODEL, (void*) L"Could not decode utf-8. An unknown error occured."); 
    } 
} 

// 
// item_allocator.c 
// 

/** 
* Allocates the item. 
* 
* @param p0 the item (pointer reference) 
* @param p1 the size 
* @param p2 the type 
*/ 
void allocate_item(void* p0, void* p1, void* p2) { 

    if (p0 != *NULL_POINTER_STATE_CYBOI_MODEL) { 

     void** i = (void**) p0; 

     log_message_terminated((void*) DEBUG_LEVEL_LOG_CYBOI_MODEL, (void*) L"Allocate item."); 

     // Allocate item. 
     allocate_array(p0, (void*) ITEM_STATE_CYBOI_MODEL_COUNT, (void*) POINTER_STATE_CYBOI_TYPE); 

     // The data, count, size. 
     void* d = *NULL_POINTER_STATE_CYBOI_MODEL; 
     void* c = *NULL_POINTER_STATE_CYBOI_MODEL; 
     void* s = *NULL_POINTER_STATE_CYBOI_MODEL; 

     // Allocate data, count, size. 
     allocate_array((void*) &d, p1, p2); 
     allocate_array((void*) &c, (void*) PRIMITIVE_STATE_CYBOI_MODEL_COUNT, (void*) INTEGER_NUMBER_STATE_CYBOI_TYPE); 
     allocate_array((void*) &s, (void*) PRIMITIVE_STATE_CYBOI_MODEL_COUNT, (void*) INTEGER_NUMBER_STATE_CYBOI_TYPE); 

     // Initialise count, size. 
     // The data does NOT have to be initialised and remains empty. 
     // The count is set to zero, since the model does not contain any elements yet. 
     // The size is set to the value that was handed over as argument. 
     copy_integer(c, (void*) NUMBER_0_INTEGER_STATE_CYBOI_MODEL); 
     copy_integer(s, p1); 

     // Set data, count, size. 
     copy_array_forward(*i, (void*) &d, (void*) POINTER_STATE_CYBOI_TYPE, (void*) PRIMITIVE_STATE_CYBOI_MODEL_COUNT, (void*) DATA_ITEM_STATE_CYBOI_NAME, (void*) VALUE_PRIMITIVE_STATE_CYBOI_NAME); 
     copy_array_forward(*i, (void*) &c, (void*) POINTER_STATE_CYBOI_TYPE, (void*) PRIMITIVE_STATE_CYBOI_MODEL_COUNT, (void*) COUNT_ITEM_STATE_CYBOI_NAME, (void*) VALUE_PRIMITIVE_STATE_CYBOI_NAME); 
     copy_array_forward(*i, (void*) &s, (void*) POINTER_STATE_CYBOI_TYPE, (void*) PRIMITIVE_STATE_CYBOI_MODEL_COUNT, (void*) SIZE_ITEM_STATE_CYBOI_NAME, (void*) VALUE_PRIMITIVE_STATE_CYBOI_NAME); 

    } else { 

     log_message_terminated((void*) ERROR_LEVEL_LOG_CYBOI_MODEL, (void*) L"Could not allocate item. The item is null."); 
    } 
} 

// 
// array_allocator.c 
// 

/** 
* Allocates the array. 
* 
* @param p0 the array (pointer reference) 
* @param p1 the size 
* @param p2 the type 
*/ 
void allocate_array(void* p0, void* p1, void* p2) { 

    if (p0 != *NULL_POINTER_STATE_CYBOI_MODEL) { 

     void** a = (void**) p0; 

     log_message_terminated((void*) DEBUG_LEVEL_LOG_CYBOI_MODEL, (void*) L"Allocate array."); 

     // The memory area. 
     size_t ma = *NUMBER_0_INTEGER_STATE_CYBOI_MODEL; 

     // Determine type (type) size. 
     determine_size((void*) &ma, p2); 

     // Calculate memory area. 
     calculate_integer_multiply((void*) &ma, p1); 

     // A minimal space in memory is always allocated, 
     // even if the requested size is zero. 
     // In other words, a handle to the new instance is always returned. 
     *a = malloc(ma); 

     // Initialise array elements with null pointer. 
     // 
     // CAUTION! Initialising with zero is essential, since cyboi 
     // frequently tests variables for null pointer values. 
     memset(*a, *NUMBER_0_INTEGER_STATE_CYBOI_MODEL, ma); 

    } else { 

     log_message_terminated((void*) ERROR_LEVEL_LOG_CYBOI_MODEL, (void*) L"Could not allocate array. The array is null."); 
    } 
} 

// 
// size_determiner.c 
// 

/** 
* Determines the size of the given type. 
* 
* @param p0 the size 
* @param p1 the type 
*/ 
void determine_size(void* p0, void* p1) { 

    if (p1 != *NULL_POINTER_STATE_CYBOI_MODEL) { 

     int* t = (int*) p1; 

     // CAUTION! Do NOT call the logger here. 
     // It uses functions causing circular references. 
     // log_message_terminated((void*) DEBUG_LEVEL_LOG_CYBOI_MODEL, (void*) L"Determine size."); 

     // 
     // datetime 
     // 

     if (*t == *DATETIME_STATE_CYBOI_TYPE) { 

      // CAUTION! This type IS NEEDED, e.g. when DEEP copying a part. 
      // It is actually a pointer array, of which each 
      // pointer references a structure element. 
      copy_integer(p0, (void*) POINTER_TYPE_SIZE); 

     // 
     // element 
     // 

     } else if (*t == *PART_ELEMENT_STATE_CYBOI_TYPE) { 

      // CAUTION! This type IS NEEDED, e.g. when DEEP copying a part 
      // or when setting the references of a part 
      // for rubbish (garbage) collection. 
      // It is actually a pointer array, of which each 
      // pointer references a structure element. 
      copy_integer(p0, (void*) POINTER_TYPE_SIZE); 

     // 
     // logicvalue 
     // 

     } else if (*t == *BOOLEAN_LOGICVALUE_STATE_CYBOI_TYPE) { 

      copy_integer(p0, (void*) SIGNED_INTEGER_INTEGRAL_TYPE_SIZE); 

     // 
     // number 
     // 

     } else if (*t == *COMPLEX_NUMBER_STATE_CYBOI_TYPE) { 

      // CAUTION! This type IS NEEDED, e.g. when DEEP copying a part. 
      // It is actually a pointer array, of which each 
      // pointer references a structure element. 
      copy_integer(p0, (void*) POINTER_TYPE_SIZE); 

     } else if (*t == *DOUBLE_NUMBER_STATE_CYBOI_TYPE) { 

      copy_integer(p0, (void*) DOUBLE_REAL_TYPE_SIZE); 

     } else if (*t == *FRACTION_NUMBER_STATE_CYBOI_TYPE) { 

      // CAUTION! This type IS NEEDED, e.g. when DEEP copying a part. 
      // It is actually a pointer array, of which each 
      // pointer references a structure element. 
      copy_integer(p0, (void*) POINTER_TYPE_SIZE); 

     } else if (*t == *INTEGER_NUMBER_STATE_CYBOI_TYPE) { 

      copy_integer(p0, (void*) SIGNED_INTEGER_INTEGRAL_TYPE_SIZE); 

     } else if (*t == *UNSIGNED_LONG_NUMBER_STATE_CYBOI_TYPE) { 

      copy_integer(p0, (void*) UNSIGNED_LONG_INTEGER_INTEGRAL_TYPE_SIZE); 

     // 
     // pointer 
     // 

     } else if (*t == *POINTER_STATE_CYBOI_TYPE) { 

      copy_integer(p0, (void*) POINTER_TYPE_SIZE); 

     // 
     // text 
     // 

     } else if (*t == *CHARACTER_TEXT_STATE_CYBOI_TYPE) { 

      copy_integer(p0, (void*) SIGNED_CHARACTER_INTEGRAL_TYPE_SIZE); 

     } else if (*t == *WIDE_CHARACTER_TEXT_STATE_CYBOI_TYPE) { 

      copy_integer(p0, (void*) WIDE_CHARACTER_INTEGRAL_TYPE_SIZE); 

     } else { 

      // CAUTION! Do NOT call the logger here. 
      // It uses functions causing circular references. 
      // log_message_terminated((void*) WARNING_LEVEL_LOG_CYBOI_MODEL, (void*) L"Could not determine size. The type is unknown."); 
     } 

    } else { 

     // CAUTION! Do NOT call the logger here. 
     // It uses functions causing circular references. 
     // log_message_terminated((void*) ERROR_LEVEL_LOG_CYBOI_MODEL, (void*) L"Could not determine size. The type is null."); 
    } 
} 

उत्तर

8

utf_8_decoder.c में लाइन 201 पर, आप

fwprintf(stdout, L"TEST decoder *ds: %i\n", *((int*) ds)); 

ताकि आप एक int* रूप ds इलाज और कहा कि ठीक काम करता है है। लेकिन लाइनों लाइनों 298 और 300 है कि valgrind ने संकेत दिया गया पर,

fwprintf(stdout, L"TEST decoder *ds pre mbsnrtowcs as size_t: %i\n", *((size_t*) ds)); 

int n = mbsnrtowcs((wchar_t*) dd, (const char**) &sd, *((size_t*) sc), *((size_t*) ds), (mbstate_t*) *NULL_POINTER_STATE_CYBOI_MODEL); 

आप एक size_t* रूप ds व्यवहार करते हैं। एक int में आमतौर पर चार बाइट होते हैं, लेकिन size_t में किसी भी आत्म-सम्मान 64-बिट सिस्टम पर आठ बाइट हैं।

+0

टिप्पणी "size_t में किसी भी आत्म-सम्मान 64-बिटसिस्टम पर आठ बाइट्स हैं" वास्तव में एक उपयोगी संकेत है। मुझे यह नहीं पता था। CYBOI प्रकार के आकार का प्रतिनिधित्व करने के लिए int का उपयोग करता है और एक glibc फ़ंक्शन को कॉल करते समय, मैंने बस size_t पर डाला। मुझे लगता है मुझे कोड में और जगहें बदलनी हैं। कल काम पर मेरे 64 बिट बॉक्स पर इसे देखेंगे। अभी के लिए धन्यवाद, ईसाई –

+0

हाँ, वह था। एक बार फिर धन्यवाद! चूंकि मैं अपने कोड पर मानक "int" चर के साथ काम करता हूं, इसलिए अब मैं एक glibc फ़ंक्शन को कॉल करने से पहले "size_t" प्रकार का एक नया स्थानीय चर प्रस्तुत करता हूं और इसे "int" चर का मान निर्दिष्ट करता हूं। "Size_t" प्रकार के चर को तब glibc फ़ंक्शन के लिए पैरामीटर के रूप में सौंप दिया जाता है। –

0

दिनचर्या decode_utf_8 एक जगह है जहाँ आप केवल 4. आवंटित जब से तुम यह भी कहना है कि यह केवल एक 64 बिट मशीन पर और 32 बिट पर होता है पर 8 बाइट्स पढ़ने के लिए कोशिश कर रहा है यह ठीक काम करता है, यह एक संकेत है कि आपके पास कहीं पूर्णांक या सूचक प्रकार के आकार के बारे में झूठी धारणा है। आप हमें decode_utf_8 नहीं दिखाते हैं, इसलिए कुछ और कहकर शुद्ध अटकलें होगी।

+0

मैंने अपने स्रोत कोड स्निपेट में "decode_utf_8" फ़ंक्शन की प्रतिलिपि बनाई है। बस नीचे स्क्रॉल करें। –

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