Unregelmäßiges Leck in unbekanntem Modul mit JNA [geschlossen]Java

Java-Forum
Guest
 Unregelmäßiges Leck in unbekanntem Modul mit JNA [geschlossen]

Post by Guest »

TL;DR: Falsch positiver (?) Speicherverlust im „unbekannten Modul“ in einem großen JNA-Projekt. Verschwindet, wenn ich versuche, ein Minimalbeispiel zu machen. Wie kann ich das Problem beheben?
Ich habe ein Java+Kotlin-Connector-Projekt für eine native Bibliothek (nennen wir sie libfoo.so) mit JNA erstellt, für das etwa 100 Komponententests geschrieben wurden dafür und wollte sehen, ob in diesen Tests irgendwelche Lecks in libfoo auftreten. Was ich jetzt getan habe, um nach ihnen zu suchen:
  • Verwenden Sie einen Ubuntu 24.04-Docker mit Clang 17, um dieses Problem zu vermeiden; Mein Hostsystem ist ein aktuelles Arch Linux.
  • kompiliere libfoo mit Adressbereinigung und lege es auf einen Pfad, wo JNA es findet
  • Code: Select all

    export LD_PRELOAD="/usr/lib/llvm-17/lib/clang/17/lib/linux/libclang_rt.asan-x86_64.so"
  • Code: Select all

    export ASAN_OPTIONS="handle_segv=0"
    um dieses Problem zu vermeiden
  • erstellen Sie eine Datei lsan.supp mit dem Inhalt „leak:libjvm\nleak:libjli\nleak:libz\nleak:liblcms\nleak: liblcms2\nleak:libawt\n" und fügen Sie es zu LSAN_OPTIONS envvar hinzu, da Java viele falsch positive „Lecks“ verursacht und Ich interessiere mich nicht für diese, nur für libfoo
  • run gradlew build, um das Projekt neu zu erstellen und zu testen; gradlew sollte ein automatisch generiertes Standardskript sein (ich bin kein Java-Typ und nicht der Autor dieses Projekts), relevanter Inhalt von build.gradle unten – beachten Sie, dass es auf Java Version 11 abzielt

Code: Select all

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
}
}
Die Hauptaufgabe war ein Erfolg! Es ist mir gelungen, einige Lecks zu beheben. Allerdings tritt von Zeit zu Zeit eine Gruppe von Lecks auf, und sie befinden sich nicht in einer dem Symbolisierer bekannten Bibliothek, sondern in einem unbekannten Modul. Sie sehen aus wie

Code: Select all

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  ()
Die genaue Anzahl der durchgesickerten Bytes variiert, ist aber ähnlich gering. Die genaue Anzahl der separat gemeldeten Lecks variiert ebenfalls zwischen 2 und ... 0. Ja, manchmal wird kein Leck gemeldet und es ist viel Dies ist wahrscheinlicher, wenn ich die meisten Unit-Tests lösche, was es zu einem absoluten Albtraum macht, ein Minimalbeispiel zu erstellen. Ich konnte es nicht einmal einer kleinen Gruppe von Tests zuordnen, denn wenn ich eine Hälfte (beide Hälften) lösche, tritt dieses „Leck“ nicht auf.
Ich vermute, dass wann Die Ausführung dauert lange genug oder ist komplex genug, etwas Java? Bibliotheken werden zum Zeitpunkt der Leckanalyse entladen. Ich glaube nicht, dass es sich um ein tatsächliches Leck handelt, da es nicht immer auftritt, und auch nicht, dass es ein Problem mit libfoo selbst ist, da es seit einigen Jahren gerne in der Produktion verwendet wird.
Dinge, die ich in Betracht gezogen/ausprobiert habe:
  • Ich dachte, dass die fraglichen entladenen Bibliotheken mit dem Laden von Bildern (Teilen von Texteinbauten) zu tun haben javax.imageio.ImageIO, da es ein ähnlich unregelmäßiges Leck gab, bei dem liblcms oder liblcms2 manchmal auftraten, aber das Vorladen dieser Bibliotheken half nicht.
    < li>Das Festlegen von LD_DEBUG envvar erzeugt Tausende von Ausgabezeilen, auch wenn es nur LD_DEBUG=libs ist, aber ich kann darin nichts Nützliches finden.
  • Die Verwendung nur eines Tests mit langer Wartezeit hilft nicht, das Problem muss spezifischer bei den hier verwendeten Tests liegen.
  • Leider kann ich den nativen Test nicht posten lib oder sogar die vollständigen Unit-Tests, da alles proprietär ist. Vielleicht werde ich es irgendwann auf etwas hinreichend Anonymes vereinfachen, aber es ist eine Menge Arbeit aufgrund der schieren Anzahl an Tests und des Herumbastelns daran, um sicherzustellen, dass das Leck normalerweise auftritt.
  • Ich habe gesucht Möglichkeiten zur Unterdrückung unbekannter Modullecks, es wurde jedoch keine LSA-Einstellung dafür gefunden.
  • Es ist nicht spezifisch für nur eine Version des Compilers für native Bibliothek, Sanitizer, Build-System, Host-System, Gradle Version oder Ziel-Java-Version (derzeit 11). Es ist seit mindestens 2 Jahren vorhanden und alle diese Dinge wurden aktualisiert, aber der Fehler bleibt bestehen.
Wie kann ich diese Speicherlecks beheben, die nur auftreten Adressenbereinigungsbibliothek enthalten und niemals als Lecks gemeldet werden (beheben, unterdrücken oder auf andere Weise)?
Ich kann immer auf „Rückgabe verwerfen“ zurückgreifen Wert, lassen Sie jemanden manuell prüfen, ob ein Leck in libfoo vorliegt wird gemeldet“-Ansatz, aber ich würde ihn gerne sauber automatisieren, indem ich dafür sorge, dass diese Lecks nicht gemeldet werden.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post