Обнаружена ошибка *** glibc обнаружен *** free(): неверный следующий размер (быстро)

См. вопрос MSO длинный список возможных дубликатов — выделение памяти C и превышение границ для получения информации о тесно связанных вопросах.


Среда разработки: CentOS 4.7, Kdevelop 3.1.1, gcc 3.4.6

Я запускаю тестовый клиент Java, который загружает общую библиотеку C++ с помощью JNI. В моем приложении есть три компонента,

  1. Java-клиент
  2. Общая библиотека C++, которая действует как оболочка JNI. (я назову это «библиотекой-оболочкой»)
  3. Общая библиотека C++, содержащая бизнес-объекты. (я назову это «бизнес-библиотека»)

Когда я запускаю клиент, я очень часто сталкиваюсь с ошибкой *** glibc detected *** free(): invalid next size (fast): 0x080eeef8 ***. Эта ошибка возникает примерно 10-11 раз, а затем приложение запускается.

В моем Java-клиенте я сначала загружаю необходимые библиотеки C++ в статический ctor следующим образом:

static
{
System.Load("/root/Desktop/libs/businesslibrary");
System.out.println("business library loaded");
System.Load("/root/Desktop/libs/wrapperlibrary");
System.out.println("wrapper library loaded");
}

В консоли печатается оператор «бизнес-библиотека загружена», но после него появляется ошибка *** glibc....

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

static
{
System.Load("/root/Desktop/libs/wrapperlibrary");
System.out.println("wrapper library loaded");
}

затем сначала загружается бизнес-библиотека (видно через ведение журнала создания глобальной переменной), а затем загружается библиотека-оболочка. Элемент управления возвращается обратно к Java-клиенту, и на консоли печатается оператор «библиотека-оболочка загружена». После этого происходит вызов нативного метода. Но управление никогда не достигает реализации этого нативного метода. Скорее перед этим снова приходит ошибка *** glibc.... Также, если я вставлю вызов статического метода другого класса java перед вызовом собственного метода, например,

static
{
 System.Load("/root/Desktop/libs/wrapperlibrary");
 System.out.println("wrapper library loaded");
 System.out.println(Try.temp()); //where temp is a static method of Try class which returns a string.

 native method call;

 --
 --
}

тогда вывод Try.temp() никогда не будет напечатан.

Каковы могут быть возможные причины проблемы в обоих этих подходах и как мне действовать?


person HS.    schedule 23.02.2010    source источник
comment
Кажется, проблема в вашей общей библиотеке.   -  person Adil    schedule 23.02.2010
comment
@Laurynas - Valgrind показал мне две ошибки, но упомянул только адреса, а не фактический код даже в отладочной сборке. Итак, не знаю, что делать дальше. Вставка фрагмента вывода из-за нехватки места. ==23002== Перейти к неверному адресу, указанному в следующей строке ==23002== по адресу 0x246: ??? ==23002== Адрес 0x246 не стек, malloc или (недавно) освобожден ==23002== ==23002== Процесс завершается с действием по умолчанию сигнала 11 (SIGSEGV) ==23002== Плохо разрешения для отображаемой области по адресу 0x246 == 23002 == по адресу 0x246: ???   -  person HS.    schedule 26.02.2010
comment
@Adil - Общая библиотека отлично работает при использовании с исполняемым файлом C ++, но вызывает проблемы при загрузке через Java. Я видел, что проблема, по-видимому, возникает на этапе загрузки общей библиотеки.   -  person HS.    schedule 26.02.2010
comment
Адрес @HS 0x246 выглядит определенно неправильным в качестве цели перехода. Есть ли дополнительные строки, которые говорят не по адресу 0xADDRESS, а по адресу 0xADDRESS?   -  person Laurynas Biveinis    schedule 01.03.2010


Ответы (2)


Возможно, сама Java связана с другой glibc, чем ваши библиотеки, или что библиотеки связаны иначе/с разными glibc.
Также проверьте, не связывается ли одна из библиотек с отладочной версией glibc (если эта проблема в Windows с библиотекой времени выполнения C++). Попробуйте статически связать свои библиотеки с glibc или ради исключения возможности статического связывания вашей оболочки и бизнес-библиотек в одну библиотеку.

person Dominik Fretz    schedule 06.04.2010
comment
Решение чем-то похоже на ваше предложение - оно касается связывания. Бизнес-библиотека имеет собственную переопределенную реализацию API для широких символов, поскольку она работает с 2-байтовым Unicode. Ожидалось, что он будет ссылаться на эти API, но он был динамически связан с системными API, которые ожидают размер 4. Я изменил имена переопределенных API, чтобы исправить это. Теперь и оболочка, и бизнес-библиотека связаны с переопределенным API. Спасибо. - person HS.; 20.04.2010
comment
@HS: Если вы решите проблему самостоятельно, вы можете опубликовать решение как ответ и принять его, чтобы другие могли его найти. - person Björn Pollex; 20.01.2011

Я сталкивался с этой загадочной ошибкой несколько раз.

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

Исправление заключалось в очень тщательной проверке правильности размещения каждого массива и в том, что ссылки на элементы массива никогда не выходили за пределы.

person Boffin    schedule 03.06.2016