Как получить ошибку двойного освобождения во время выполнения в моем коде C ++

Я использую библиотеку Jansson в моем коде C ++. В библиотеке, когда создается любая переменная Jansson, переменная должна быть освобождена, чтобы освободить ссылку, и я использую метод ‘json_decref (json_t * json)’ для освобождения.
Но иногда это вызывает проблему двойного освобождения, и я не получил проблему во время выполнения. Возможно, это не нормально, но я хочу получить ошибку во время выполнения, когда пытаюсь освободить некоторые ссылки. Например, я запускаю следующий тестовый код,

json_t *root = json_loads(any_json_message, 0, &error);
json_decref(root);
json_decref(root);

Как вы видите, есть проблема, и я не получаю никаких ошибок во время выполнения, как double free.

Кроме того, я использую CMake для компиляции моего исходного кода. Может быть, любой флаг cmake исправит мой вопрос.

Любая идея ?

2

Решение

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

Возможно, это не нормально, но я хочу получить ошибку во время выполнения, когда пытаюсь освободить некоторые ссылки.

Ну, Янссон не дает это тебе.

Ваш компилятор может предоставить анализатор времени выполнения, который сможет обнаружить некоторое неопределенное поведение и завершить программу сообщением. Смотрите руководство вашего компилятора для того, как использовать анализатор.

1

Другие решения

В документации сказано, что json_t содержит количество ссылок. Я думаю, что первый звонок json_decref уменьшает счетчик ссылок с 1 до 0 и освобождает память. Второй звонок json_decref видит, что счетчик ссылок равен 0, и ничего не делает.

Чтобы сгенерировать ошибку double-free, вы должны скопировать старое содержимое json_t объект. Примерно так (но не буквально; см. Ниже):

json_t *root = json_loads(any_json_message, 0, &error);
json_t copy = *root;
json_decref(root);
json_decref(&copy);

Тем не мение, json_t это (я думаю) непрозрачный тип, то есть пользователи могут создавать только указатели на него, а не объекты. Чтобы принудительно создать копию объекта, вы можете угадать размер json_t объект и использование memcpy:

json_t *root = json_loads(any_json_message, 0, &error);
char copy[42];
memcpy(copy, root, sizeof copy);
json_decref(root);
json_decref((json_t *)copy);

Попробуйте с различными размерами (вместо 42), пока он не работает. Однако я не уверен, что вы можете заставить его работать — это всего лишь предположение о том, как работают внутренние компоненты этой библиотеки.

0

По вопросам рекламы [email protected]