因爲幾天我試圖在我的軟件中發現內存錯誤。
這是相當複雜的,但結構良好,格式(在我看來)。
該錯誤出現在運行Debian GNU/Linux的64位機器上。
(...不在我的32位機器上 - void */int mixup?)
如果你能幫助我,我會非常高興。valgrind |無效的大小爲8的閱讀地址0x7a41270在大小爲4的塊內是0字節alloc'd
源代碼片段在此消息結尾處顯示。
如果沒有足夠的,你可能想從購物結帳來源:
http://savannah.nongnu.org/svn/?group=cybop
按照INSTALL文件的編譯和運行的說明。
運行如下軟件正常工作:
enter code here
基督教@天津四:/首頁/項目/ cybop /例子$ ../src/controller/cyboi
與選項來運行它帶來MEMCHECK錯誤在Valgrind的:
基督教@天津四:/首頁/項目/ cybop /例子$ ../src/controller/cyboi --help
我已經使用這個命令行運行MEMCHECK:
基督教@天津四:/ home/project/cybop/examples $ valgrind --log-file = memche ck.log --tool = MEMCHECK --read-VAR-INFO = YES --track-起源= YES ../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
......產生這些錯誤:
cyboi:mallo cc:3096:sYSMALLOc:Assertion`(old_top ==(((mbinptr) (((char *)&((av) - > bins [((1) - 1)* 2]))__builtin_offsetof(struct malloc_chunk,fd))))& & old_size == 0)|| ((無符號長)(old_size)
=(無符號長整數)((((__ builtin_offsetof(結構個malloc_chunk,fd_nextsize))+((2 *(的sizeof(爲size_t))) - 1))&〜( (2 *(的sizeof(爲size_t))) - 1)))& &((old_top) - >大小爲0x1 &)& &((無符號長整數)OLD_END & pagemask)== 0)」失敗。 Aborted
任何幫助將非常感激。 我真的不知道在哪個地方進行調試。
的源代碼如下:
//
// 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.");
}
}
備註「size_t在任何自我尊重的64位系統上都有8個字節」是一個非常有用的提示。我不知道。 BermI使用int來表示字體大小,當調用glibc函數時,我只是將其轉換爲size_t。我想我必須在代碼中改變更多的地方。將在明天工作時在我的64位盒子上檢查它。謝謝你,Christian –
是的,就是這樣。再次感謝!由於我在我的代碼中使用了標準的「int」變量,所以我現在只是在調用glibc函數之前引入一個類型爲「size_t」的新局部變量並將其賦值爲「int」變量的值。然後將類型「size_t」的變量作爲參數移交給glibc函數。 –