Почему мой код перестает работать после добавления библиотеки aSan? - PullRequest
0 голосов
/ 05 марта 2020

Я сейчас отлаживаю код C. Это в основном клиент с платформы сбора данных, и я получал странные сообщения об ошибках из связанного списка. В основном проблема заключается в том, что указатель «следующий» последнего элемента изменяется в некоторой неизвестной точке с NULL на 0xFFFFFFFFF. Затем я попытался скомпилировать свою библиотеку с помощью средства очистки адреса, чтобы определить, где может быть ошибка и ошибка исчезла, или было бы лучше сказать, что ошибка в настоящее время скрыта. Является ли это возможным? Как библиотека Asan может повлиять на код, чтобы не сделать cra sh? заранее спасибо.

РЕДАКТИРОВАТЬ: Извините за плохое описание, я постараюсь go глубже. Я отлаживал код и нашел, где проблема. Он находится в функции синтаксического анализа из файла конфигурации json (для этого я использую библиотеку jansson). Формат json выглядит следующим образом:

{
...
"version": {
            "software": "0.2",
            "firmware": "0.2"
        },     
"system": ["system_A", "system_B"],
...
"internal_devices : [
         {
             ...
             "version": {
                 "software": "0.2",
                 "firmware": "0.2"
             },     
             "system": ["system_B"],
             ...
             },
             ...
             "version" : {
                 "software": "0.2",
                 "firmware": "0.2"
              },     
              "system": ["system_A"],
               ...
               }
           ]
      }
}   

И у меня есть такая структура для хранения этих данных

typedef struct XXX_NODE {
    mqtt_client_t * client;
    XXX_Device devices[XXX_MAX_DEVICES];
    size_t num_devices;
    XXX_operation_mode mode;
    pthread_mutex_t callback_lock;
    pthread_mutex_t registration_lock;
    pthread_cond_t registration_condition;
}XXX_NODE;

typedef struct XXX_id {
    ...
    struct XXX_parent parent_unit;
    // char parent_fin[64];
    int internal_level_tree;
    XXX_version version;
    List XXX_systems;
    List extended_topics;
    bool registered;
}XXX_id;

Настоящая проблема в List XXX_systems. У меня есть список на устройство, и у меня может быть несколько устройств в одной структуре, где первый элемент (в массиве устройств XXX_Device) является основным блоком. И именно в этом устройстве я теряю информацию. Функция синтаксического анализа выглядит правильно. В конце функции структура имеет значения прав, но когда я освобождаю json "объекты", я теряю ссылку на XXX_systems->next, но странная вещь, если я не освобождаю некоторые json " объекты ", все работает ...

Итак, в этом случае я теряю информацию:

json_decref(internal_list);
json_decref(unit);
json_decref(root);
return 0;

Но если я прокомментирую json_decref, как это

json_decref(internal_list);
//json_decref(unit);
json_decref(root);
return 0; 

все работает ...

1 Ответ

0 голосов
/ 06 апреля 2020

Из вашего описания похоже, что вызов json_decref() приводит к повреждению ваших данных. По-видимому, часть данных, идентифицированных переменной unit, уничтожается, и затем вы пытаетесь использовать ее, возможно, из какого-то отдельного фрагмента кода.

Я вижу два наиболее вероятных сценария ios:

  • Либо у вас есть несколько «пользователей» некоторых данных, и вам может быть неважно правильно определить «владельца» среди «пользователей», поэтому somone решает удалить данные, которые все еще используются;
  • Или вы забыли идентифицировать некоторых пользователей, поэтому объект данных в какой-то момент кажется неиспользованным и удаляется, пока кто-то все еще ссылается на него.

Я ничего не знаю о базовых вопросах Янссона, но я просто спросил Google о json_decref, и он нашел описание библиотеки Янссона. См. Раздел по подсчету ссылок:

https://jansson.readthedocs.io/en/2.8/apiref.html#reference -счет

Там четко указано, что json_decref() уменьшает счетчик ссылок и удаляет объект, если количество падает до нуля. Следующая заметка описывает создание так называемых заимствованных ссылок и указывает, что держатель такой ссылки должен вызывать json_incref(). Это предотвращает удаление объекта во время использования. Как только значение больше не требуется, необходимо вызвать json_decref(), чтобы освободить ссылку (и, возможно, удалить объект данных).

Вывод: вы, скорее всего, пропустили json_incref() в некоторых часть кода, которая хранит ссылку для будущего использования. В результате счетчик ссылок слишком мал и обнуляется слишком рано, что приводит к преждевременному удалению. Это сценарий номер два.

Просканируйте ваш код и структуры данных на наличие сохраненных ссылок на Json объектов данных и убедитесь, что каждый раз, когда сохраняется непустая ссылка, вы вызываете json_incref() для нее, и каждый время, когда непустая ссылка перезаписывается или выходит из области видимости, которую вы называете json_decref().

ПРИМЕЧАНИЕ:
Distin guish осторожно между заимствованной ссылкой и украденная ссылка - последняя также описана на связанной странице do c.

PS
Похоже, ваша проблема не имеет ничего общего с языком C, но скорее с неправильным использованием библиотеки Янссона. Пожалуйста, рассмотрите возможность удаления ненужного тега .

...