Нерегулярная утечка в неизвестном модуле с JNAJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Нерегулярная утечка в неизвестном модуле с JNA

Сообщение Anonymous »

TL;DR: ложноположительная(?) утечка памяти в «неизвестном модуле» в большом проекте JNA. Исчезает, когда я пытаюсь сделать минимальный пример. Как это исправить?
Я взял проект коннектора Java+Kotlin для собственной библиотеки (назовем ее libfoo.so), используя JNA, для которой было написано около 100 модульных тестов. для этого и хотел посмотреть, не произойдет ли какая-либо утечка в libfoo в этих тестах. Что я сделал, чтобы их найти сейчас:
  • использовал докер Ubuntu 24.04 с Clang 17, чтобы избежать этой проблемы; моя хост-система — последняя версия Arch Linux.
  • скомпилировать libfoo с очистителем адресов и поместить ее в путь, где JNA найдет ее.
  • Код: Выделить всё

    export LD_PRELOAD="/usr/lib/llvm-17/lib/clang/17/lib/linux/libclang_rt.asan-x86_64.so"
  • Код: Выделить всё

    export ASAN_OPTIONS="handle_segv=0"
    чтобы избежать этой проблемы
  • создайте файл lsan.supp с содержимым "leak:libjvm\nleak:libjli\nleak:libz\nleak:liblcms\nleak: liblcms2\nleak:libawt\n" и добавьте его в LSAN_OPTIONS envvar, поскольку Java дает много ложноположительных "утечек" и Меня это не интересует, только в libfoo
  • запустите gradlew build, чтобы перестроить+проверить проект; gradlew должен быть автоматически сгенерированным стандартным скриптом (я не специалист по Java и не автор этого проекта), соответствующее содержимое build.gradle ниже - обратите внимание, что он предназначен для Java версии 11.

Код: Выделить всё

plugins {
id 'distribution'
id 'jacoco'
id 'net.researchgate.release' version '2.8.1'
id 'org.jetbrains.kotlin.jvm' version '1.7.21'
}

ext {
assertjVersion = '3.23.1'
annotationsVersion = '23.0.0'
commonsLang3Version = '3.12.0'
jUnitVersion = '5.8.2'
}

allprojects {
repositories {
mavenCentral()
}
}

subprojects {
apply plugin: 'java'
apply plugin: 'kotlin'

group 'foo'
version "$version"

compileJava.options.encoding = "UTF-8"
compileTestJava.options.encoding = "UTF-8"

java {
withSourcesJar()
}

kotlin {
jvmToolchain(11)
}

compileKotlin {
kotlinOptions.jvmTarget = JavaVersion.VERSION_11
}
compileTestKotlin {
kotlinOptions.jvmTarget = JavaVersion.VERSION_11
}
}
Основная задача выполнена успешно! Мне удалось устранить некоторые утечки. Однако время от времени появляется одна группа утечек, и они находятся не в какой-либо известной символизатору библиотеке, а в неизвестном модуле. Они похожи

Код: Выделить всё

Direct leak of 4 byte(s) in 4 object(s) allocated from:
#0 0x7e475ecfb372 in malloc (/usr/lib/llvm-17/lib/clang/17/lib/linux/libclang_rt.asan-x86_64.so+0xfb372) (BuildId: 91f375f2a48c6b133a56d8cc059d017ae5de4982)
#1 0x7e4746abaa13  ()
#2 0x7e473fa103f3  ()
#3 0x7e473ee09fdf  ()
#4 0x7e473f79ff33  ()
Точное количество утечек байтов варьируется, но оно одинаково мало. Точное количество утечек, о которых сообщается отдельно, также варьируется от 2 до... 0. Да, иногда об утечках не сообщается, и это очень важно. более вероятно, что это произойдет, когда я удалю большинство модульных тестов, что делает создание минимального примера абсолютным кошмаром. Я не смог даже выделить его в небольшую группу тестов, так как при удалении половины (любой половины) эта "утечка" не появляется.
Я предполагаю, что когда выполнение занимает достаточно много времени или достаточно сложно, какая-то Java? библиотеки выгружаются к моменту проведения анализа утечек. Я не думаю, что это настоящая утечка, потому что она не всегда появляется, и что это проблема самой библиотеки libfoo, поскольку она уже несколько лет успешно используется в производстве.
Что я рассматривал/пробовал:
  • Я думал, что рассматриваемые выгруженные библиотеки участвуют в загрузке изображений (части текстовых фикстур) через javax.imageio .ImageIO, поскольку там была аналогичная нерегулярная утечка с появлением liblcms или liblcms2, но предварительная загрузка этих библиотек не помогла.
  • Установка LD_DEBUG envvar приводит к тысячам строк вывода, даже если это всего лишь LD_DEBUG=libs, но я не могу найти в нем ничего полезного.
  • Использование только одного теста с длительным ожиданием не помогает, проблема должна быть более специфичной для используемых здесь тестов.
  • К сожалению, я не могу опубликовать собственную библиотеку или даже полные модульные тесты, поскольку все они являются собственностью. Возможно, со временем я упрощу что-то достаточно анонимное, но это большая работа из-за огромного количества тестов и возни с ними, чтобы убедиться, что утечка обычно появляется.
  • Я искал способы подавления утечек неизвестных модулей, но не нашел для него никаких настроек lsan.
  • Это не относится только к одной версии компилятора для собственной библиотеки, дезинфицирующего средства, системы сборки, хост-системы, Gradle версия или целевая версия Java (в настоящее время 11). Он существует уже как минимум 2 года, и все эти вещи были обновлены, но ошибка остается.
Как я могу устранить те утечки памяти, которые только содержать библиотеку дезинфицирующих адресов и никогда не будет сообщаться как утечка (исправить, подавить или каким-либо другим способом)?
Я всегда могу вернуться к «отменить возврат» значение, попросите кого-нибудь вручную проверить наличие утечек в libfoo сообщается", но я хотел бы автоматизировать его, сделав так, чтобы об этих утечках не сообщалось.

Подробнее здесь: https://stackoverflow.com/questions/792 ... e-with-jna
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»