2011-12-24 4 views
2

Я запускаю debug-версию моего двоичного кода C в пределах valgrind, который возвращает многочисленные ошибки сортировки Conditional jump or move depends on uninitialised value(s).Где неинициализированное значение этой функции?

Используя таблицу символов, valgrind говорит мне, где искать в моей программе для этого выпуска:

==23899== 11 errors in context 72 of 72:                                                  
==23899== Conditional jump or move depends on uninitialised value(s)                                           
==23899== at 0x438BB0: _int_free (in /foo/bar/baz)                               
==23899== by 0x43CF75: free (in /foo/bar/baz)                                
==23899== by 0x4179E1: json_tokener_parse_ex (json_tokener.c:593)                                           
==23899== by 0x418DC8: json_tokener_parse (json_tokener.c:108)                                            
==23899== by 0x40122D: readJSONMetadataHeader (metadataHelpers.h:345)                                        
==23899== by 0x4019CB: main (baz.c:90) 

У меня есть следующая функция readJSONMetadataHeader(...), которая вызывает json_tokener_parse():

int readJSONMetadataHeader(...) {                                                                                         
    char buffer[METADATA_MAX_SIZE]; 
    json_object *metadataJSON; 
    int charCnt = 0; 
    ... 
    /* fill up the `buffer` variable here; basically a */ 
    /* stream of characters representing JSON data... */ 
    ... 
    /* terminate `buffer` */ 
    buffer[charCnt - 1] = '\0'; 
    ... 
    metadataJSON = json_tokener_parse(buffer); 
    ... 
} 

Функция json_tokener_parse() в поворот выглядит следующим образом:

struct json_object* json_tokener_parse(const char *str)                                              
{                                                            
    struct json_tokener* tok;                                                     
    struct json_object* obj;                                                     

    tok = json_tokener_new();                                                     
    obj = json_tokener_parse_ex(tok, str, -1);                                                 
    if(tok->err != json_tokener_success)                                                  
     obj = (struct json_object*)error_ptr(-tok->err);                                               
    json_tokener_free(tok);                                                      
    return obj;                                                         
} 

После след обратно readJSONMetadataHeader(), похоже, неинициализированное значение является char [] (или const char *) переменная buffer, что подают в json_tokener_parse(), который, в свою очередь подают в json_tokener_parse_ex().

Но переменная buffer заполняется данными, а затем прекращается до того, как вызывается функция json_tokener_parse().

Так почему же valgrind говорит, что это значение неинициализировано? Что мне не хватает?

+0

Если ваш код и комментарии - что-то в этом роде, 'charCnt' неинициализируется, когда он используется. – GManNickG

+0

Или, может быть, 'buffer' является унифицированным, только NUL-terminated. – cnicutar

+0

Извините за отсутствие ясности. Когда 'buffer' заполняется значениями' char', значение 'charCnt' увеличивается. И я копирую и вставляю только релевантные переменные. Я забыл написать, что он инициализирован '0', который теперь исправлен. Благодаря! –

ответ

2

Я не вижу charCnt инициализирован.

Чтобы узнать, исходит ли оно от buffer, просто инициализируйте его = {0}, это также приведет к тому, что ваше нулевое завершение работы буфера устареет.

+0

Я попытался добавить '{0}' в 'buffer', но я продолжаю получать ту же ошибку и в тех же функциях и в тех же строках. –

1

Посмотрите на json_tokener_parse_ex(), который вы не показываете. Скорее всего, он пытается освободить то, что не инициализировано.

1
buffer[charCnt - 1] = '\0'; 

Это по крайней мере потерпеть неудачу, если charCnt бывает равным нулю.

+0

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

2

Он выглядит из отчета об ошибке valgrind, как будто ваше приложение статически связано (в частности, free похоже находится в основном исполняемом файле, а не libc.so.6).

Valgrind сообщит о ложных ошибках для статически связанных приложений.

Точнее, внутри libc есть намеренные ошибки «неважно». При динамическом связывании приложения такие ошибки подавляются по умолчанию (через файл подавления, который поставляется с Valgrind).

Но при связывании приложения статически Valgrind не имеет понятия, что неисправный код исходит из libc.a, и поэтому он сообщает об этом.

Как правило, статическая привязка приложений к Linux - это плохая идея (TM).

Запуск такого приложения под Valgrind: дважды так: Valgrind не сможет перехватить malloc/free вызов, и будет эффективно ловить только неинициализированная память читает и не кучи переполнение буфера (или другие ошибки кучи коррупции) что это обычно хорош.

Смежные вопросы