Я исправляю проблему, которая возникает только в порте PPC64 моей программы.
У меня есть тестовый пример, в котором библиотеке C qsort
предоставляется замыкание, сгенерированное libffi, в качестве обратного вызова сравнения строк. Строки правильно передаются обратному вызову, а возвращаемое значение сохраняется именно в буфере возвращаемого значения, переданном libffi функции закрытия.
Однако массив неправильно отсортирован по qsort
. Более того, Valgrind сообщает, что код qsort библиотеки C обращается к неинициализированной памяти, а --track-orgins=yes
показывает, что эта память была выделена Libffi в стеке. Я сильно подозреваю, что это возвращаемое значение, и поэтому сортировка неверна из-за сравнений мусора.
т.е. Libffi выделила буфер для возвращаемого значения и передает это значение вызывающей стороне обратного вызова; но моя функция отправки закрытия получает неправильный указатель, и поэтому возвращаемое значение не помещается в нужное место.
По какой-то странной причине Valgrind не сообщает адрес неинициализированной памяти, а только то, где в коде произошло использование и где она была выделена.
Я просто хочу сравнить адрес этого места с указателем, который передается функции закрытия: они хоть отдаленно близки?
Есть ли способ получить эту информацию от Valgrind?
ОБНОВЛЕНИЕ: я работаю на машине GCC Compile Farm, где у меня нет root; установленная libffi не имеет отладочной информации. Это версия 3.0.13.
Тем не менее, проблема воспроизводится с головой libffi
git, которую я только что создал.
Я подтвердил, что это область возвращаемого значения, которая не инициализирована.
Я добавил инструкцию в ассемблерный код диспетчеризации замыкания ffi_closure_LINUX64
для инициализации области размером в двойное слово в нижней части RETVAL
части кадра стека диспетчеризации замыкания. Это устраняет ошибку Valgrind; но, конечно, возвращаемое значение - мусор. Это также подтверждает базовую часть здравого смысла: код перед вызовом помощника отправки закрытия и код после ссылаются на одну и ту же область для возвращаемого значения. (Указатель стека не перемещался неожиданно, и ссылки на фреймы верны.) Любой адрес, который в конечном итоге получает пользовательский код, не указывает на это возвращаемое значение.
Затем я переместил инициализацию области возврата вниз в функцию C под названием ffi_closure_helper_LINUX64
, рядом с входом в функцию. Это также по-прежнему устраняет неинициализированную ошибку, подтверждая, что помощник получает правильный адрес области возвращаемого значения через %r6
(аргумент 4).