2015-10-19 6 views
16

Ich benutze Android NDK- r10d Android x86 ausführbare (gemeinsame Verknüpfung), die auf adb-Shell läuft zu bauen. Auf der Laufzeit, erhalte ich die folgende Warnung:unbenutzte DT-Eintrag: Geben Sie 0x1d arg

WARNING: linker: ./myapp: **unused DT entry:** type 0x1d arg 0x4a604

ich verwurzelt Nexus Player bin mit der ausführbaren Datei zu testen.

Und meine Build-Maschine ist Ubuntu 14.04 (auch auf Fedora 14-Maschine versucht).

+0

die [Gerücht] (http://www.kevinboone.net/kbox3_c.html) ist, dass diese Warnung ist harmlos –

+0

RUNPATH den Suchpfad beeinflusst von .so-Dateien. Wenn es keinen Fehler gibt, dass einige .so fehlen, ist diese Warnung harmlos. –

Antwort

5

Mit readelf -d Sie Einträge DT Liste kann in die Binärdatei:

0x0000001d (RUNPATH)     Library runpath: [lib] 

Wie Sie vielleicht finden 0x1d Das Eintrag RUNPATH entspricht, wird mit Linkeroption -rpath hinzugefügt (oder -R, wenn gefolgt nach Verzeichnis)

47

Was sind "unbenutzte DT-Eingabe" -Fehler?

Wenn Sie diese Seite erreicht haben, ist es wahrscheinlich, weil Sie kompiliert oder versucht haben, einige Binärdateien auf ARM zu laufen basierte Android System, mit dem Ergebnis, dass die Binärdatei/app abstürzt oder erzeugt eine viele Warnungen in Ihre logcat. so etwas wie dies in der Regel:

WARNING: linker: /blahblah/libopenssl.so: unused DT entry: type 0x6ffffffe arg 0x1188 

Q: Was ist ein "DT Eintrag"?

In ein paar Worten, sie sind beschreibende Array-Einträge in der Datei Struktur einer ELF Datei. Insbesondere sind sie bekannt als Dynamic Array Tags und sind Anforderungen für ausführbare und gemeinsame Objekte . Es sind jedoch nicht alle Einträge erforderlich oder verfügbar, , abhängig von der Prozessor- und Kernel-Architektur.

In unserem Fall sehen wir uns mit einer "Warnung" konfrontiert, dass eine davon "unbenutzt" ist. Das bedeutet, dass Ihre ausführbare Datei oder Bibliothek (*.so) kompiliert mit DT Eintrag angegeben wurde, aber Ihr Kernel unterstützt diesen Eintrag aus verschiedenen Gründen nicht. Die besten Beispiele finden sich auf ARM-basierten Android-Systemen, bei denen die Systembibliothekspfade festgelegt sind und die Cross-Compiler, die für Ihre Firmware (OS/Kernel) verwendet werden, diese Einträge nicht verwenden. Normalerweise laufen die Binärdateien immer noch gut, aber der Kernel markiert diese Warnung jedes Mal, wenn Sie ihn verwenden.

Frage: Wann passiert das?

Dies kann passieren, wenn:

  • Ihr ARM-Kernel ist cross-compiled der falschen Fahnen (in der Regel für andere Prozessorarchitekturen gemeint).
  • Ihre ARM-Binärdateien und -Bibliotheken werden mithilfe von veralteten AOS-Kompilierungsflags kompiliert.
  • und wahrscheinlich andere Wege noch zu entdecken ..

Ausgehend von 5,1 (API 22) die Android-Linker warnen vor der VERNEED und VERNEEDNUM ELF dynamische Abschnitte.

Die häufigsten Flags, die diesen Fehler auf Android-Geräten verursachen, sind:

DT_RPATH  0x0f (15)  The DT_STRTAB string table offset of a null-terminated library search path string. 
           This element's use has been superseded by DT_RUNPATH. 
DT_RUNPATH  0x1d (29)  The DT_STRTAB string table offset of a null-terminated library search path string. 
DT_VERNEED  0x6ffffffe  The address of the version dependency table. Elements within this table contain 
           indexes into the string table DT_STRTAB. This element requires that the 
           DT_VERNEEDNUM element also be present. 
DT_VERNEEDNUM 0x6fffffff  The number of entries in the DT_VERNEEDNUM table. 

den Fehler über der Spur, wir feststellen, dass diese Nachricht von der bionic Bibliothek kommt linker.cpp:

case DT_VERNEED: 
    verneed_ptr_ = load_bias + d->d_un.d_ptr; 
    break; 

    case DT_VERNEEDNUM: 
    verneed_cnt_ = d->d_un.d_val; 
    break; 

    case DT_RUNPATH: 
    // this is parsed after we have strtab initialized (see below). 
    break; 

    default: 
    if (!relocating_linker) { 
     DL_WARN("\"%s\" unused DT entry: type %p arg %p", get_realpath(), 
      reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val)); 
    } 
    break; 
} 

Der Code (oben), der diese symbol versioning unterstützt, wurde unter April 9, 2015 festgelegt. Wenn Ihr NDK-Build also entweder früher APIs unterstützt oder Build-Tools verwendet, die mit dieser früheren Bibliothek verlinkt sind, erhalten Sie diese Warnungen.


Q: Wie finde ich, was DT mein System oder Binärdateien verwenden Einträge?

Es gibt viele Möglichkeiten, dies zu tun:

  1. Sie sehen in den Kernel-Quellen für <linux/elf.h>.
  2. Sie sehen in Ihrem Installationsordner Android NDK und überprüfen:
# To find all elf.h files: 
find /<path_to>/ndk/platforms/android-*/arch-arm*/usr/include/linux/ -iname "elf.h" 
  1. eine readelf Ihrer binären Do:
$ readelf --dynamic libopenssl.so 

Dynamic section at offset 0x23b960 contains 28 entries: 
Tag  Type       Name/Value 
0x00000003 (PLTGOT)      0x23ce18 
0x00000002 (PLTRELSZ)     952 (bytes) 
0x00000017 (JMPREL)      0x15e70 
0x00000014 (PLTREL)      REL 
0x00000011 (REL)      0x11c8 
0x00000012 (RELSZ)      85160 (bytes) 
0x00000013 (RELENT)      8 (bytes) 
0x6ffffffa (RELCOUNT)     10632 
0x00000015 (DEBUG)      0x0 
0x00000006 (SYMTAB)      0x148 
0x0000000b (SYMENT)      16 (bytes) 
0x00000005 (STRTAB)      0x918 
0x0000000a (STRSZ)      1011 (bytes) 
0x00000004 (HASH)      0xd0c 
0x00000001 (NEEDED)      Shared library: [libdl.so] 
0x00000001 (NEEDED)      Shared library: [libc.so] 
0x0000001a (FINI_ARRAY)     0x238458 
0x0000001c (FINI_ARRAYSZ)    8 (bytes) 
0x00000019 (INIT_ARRAY)     0x238460 
0x0000001b (INIT_ARRAYSZ)    16 (bytes) 
0x00000020 (PREINIT_ARRAY)    0x238470 
0x00000021 (PREINIT_ARRAYSZ)   0x8 
0x0000001e (FLAGS)      BIND_NOW 
0x6ffffffb (FLAGS_1)     Flags: NOW 
0x6ffffff0 (VERSYM)      0x108c 
0x6ffffffe (VERNEED)     0x1188 
0x6fffffff (VERNEEDNUM)     2 
0x00000000 (NULL)      0x0 

Wie Sie kann aus dem obigen Fehler sehen, type entspricht DT_VERNEED.

Von THIS Dokument: "Shared Object Abhängigkeiten"

DT_RPATH

Dieses Element der String-Tabelle einer nullterminierten Suche Bibliotheks-Suchpfadzeichenfolge, diskutierte in Offset hält Der Offset ist ein Index in die im Eintrag DT_STRTAB aufgezeichnete Tabelle. DT_RPATH kann eine Zeichenfolge geben, die eine Liste von Verzeichnissen enthält, getrennt durch durch Doppelpunkte (:). Alle LD_LIBRARY_PATH-Verzeichnisse werden nach diejenigen aus DT_RPATH durchsucht.

Frage: Wie lösen oder behandeln Sie diese Probleme?

Es gibt im Wesentlichen drei Möglichkeiten, um damit umzugehen:

  1. die schnelle
  2. die schlechte
  3. das hässliche

Der Quick (Sie don‘ Ich habe keine Quellen oder kann einfach nicht belästigt werden)

Verwenden Sie einen "ELF-Reiniger", um die störenden DT-Einträge von all Ihren Binärdateien zu entfernen. Dies ist eine einfache und schnelle Abhilfe, vor allem, wenn Sie nicht die Quellen haben, um sie für Ihr System neu zu kompilieren. Es gibt mindestens two cleaners da draußen, die Sie verwenden können.


Das Bad (Sie haben die Quellen)

ist der richtige Weg, es zu tun, weil Sie ein bad-ass ARM Cross-Compiler-Guru in den Prozess des Erhaltens sie arbeiten werden werden . Sie müssen im Grunde die Compilereinstellungen in den verwendeten Makefiles finden und optimieren.

Von here:

Der Android-Linker (/ system/bin/Linker) unterstützen RPATH oder RUNPATH nicht, so setzen wir LD_LIBRARY_PATH = $ USR/lib und versuchen, mit dem Bau nutzlos rpath Einträge zu vermeiden - -disable-rpath konfigurieren Flags. Eine andere Möglichkeit, die von LD_LIBRARY_PATH abhängig ist, wäre die Bereitstellung eines benutzerdefinierten Linkers - dies wird aufgrund des Aufwands für die Pflege eines benutzerdefinierten Linkers nicht durchgeführt.


Das hässliche (Sie wollen nur Ihre App mit jedem schmutzigen binär zu arbeiten.)

Sie sagen, Ihre Java-Anwendung ausflippen nicht, wenn für null in Fehlerbehandlungsroutinen überprüft und stattdessen füttern diese Warnungen, möglicherweise verursacht tödliche Ausnahmen. Verwenden Sie so etwas wie:

class OpensslErrorThread extends Thread { 
    @Override 
    public void run() { 
     try { 
      while(true){ 
       String line = opensslStderr.readLine(); 
       if(line == null){ 
        // OK 
        return; 
       } 
       if(line.contains("unused DT entry")){ 
        Log.i(TAG, "Ignoring \"unused DT entry\" error from openssl: " + line); 
       } else { 
        // throw exception! 
        break; 
       } 
      } 
     } catch(Exception e) { 
      Log.e(TAG, "Exception!") 
     } 
    } 
} 

Das ist sehr schlecht und hässlich wie er nichts lösen, während Ihr Code Blähungen. Außerdem gibt es die Warnungen aus einem bestimmten Grund, und das ist, dass in künftigen AOS-Versionen dies ein voller Fehler werden wird!


Frage: Was noch?

Viele Änderungen in den APIs zwischen 18-25 (J bis N) wurden in Art und Weise der Android Kernel und Bibliotheken sind kompiliert. Ich kann nicht bieten eine Remote-nahe Erklärung von all dem, aber vielleicht wird diese helfen, Sie in die richtige Richtung zu führen. Die besten Quellen sind natürlich in den Android-Quellen und Dokumentation selbst suchen.

Zum Beispiel HERE oder HERE.


Und schließlich die vollständige Liste:

Name     Value   d_un   Executable    Shared Object 
--------------------------------------------------------------------------------------------- 
DT_NULL     0    Ignored   Mandatory    Mandatory 
DT_NEEDED    1    d_val   Optional    Optional 
DT_PLTRELSZ    2    d_val   Optional    Optional 
DT_PLTGOT    3    d_ptr   Optional    Optional 
DT_HASH     4    d_ptr   Mandatory    Mandatory 
DT_STRTAB    5    d_ptr   Mandatory    Mandatory 
DT_SYMTAB    6    d_ptr   Mandatory    Mandatory 
DT_RELA     7    d_ptr   Mandatory    Optional 
DT_RELASZ    8    d_val   Mandatory    Optional 
DT_RELAENT    9    d_val   Mandatory    Optional 
DT_STRSZ    0x0a (10)  d_val   Mandatory    Mandatory 
DT_SYMENT    0x0b (11)  d_val   Mandatory    Mandatory 
DT_INIT     0x0c (12)  d_ptr   Optional    Optional 
DT_FINI     0x0d (13)  d_ptr   Optional    Optional 
DT_SONAME    0x0e (14)  d_val   Ignored     Optional 
DT_RPATH    0x0f (15)  d_val   Optional    Optional 
DT_SYMBOLIC    0x10 (16)  Ignored   Ignored     Optional 
DT_REL     0x11 (17)  d_ptr   Mandatory    Optional 
DT_RELSZ    0x12 (18)  d_val   Mandatory    Optional 
DT_RELENT    0x13 (19)  d_val   Mandatory    Optional 
DT_PLTREL    0x14 (20)  d_val   Optional    Optional 
DT_DEBUG    0x15 (21)  d_ptr   Optional    Ignored 
DT_TEXTREL    0x16 (22)  Ignored   Optional    Optional 
DT_JMPREL    0x17 (23)  d_ptr   Optional    Optional 
DT_BIND_NOW    0x18 (24)  Ignored   Optional    Optional 
DT_INIT_ARRAY   0x19 (25)  d_ptr   Optional    Optional 
DT_FINI_ARRAY   0x1a (26)  d_ptr   Optional    Optional 
DT_INIT_ARRAYSZ   0x1b (27)  d_val   Optional    Optional 
DT_FINI_ARRAYSZ   0x1c (28)  d_val   Optional    Optional 
DT_RUNPATH    0x1d (29)  d_val   Optional    Optional 
DT_FLAGS    0x1e (30)  d_val   Optional    Optional 
DT_ENCODING    0x1f (32)  Unspecified  Unspecified    Unspecified 
DT_PREINIT_ARRAY  0x20 (32)  d_ptr   Optional    Ignored 
DT_PREINIT_ARRAYSZ  0x21 (33)  d_val   Optional    Ignored 
DT_MAXPOSTAGS   0x22 (34)  Unspecified  Unspecified    Unspecified 
DT_LOOS     0x6000000d  Unspecified  Unspecified    Unspecified 
DT_SUNW_AUXILIARY  0x6000000d  d_ptr   Unspecified    Optional 
DT_SUNW_RTLDINF   0x6000000e  d_ptr   Optional    Optional 
DT_SUNW_FILTER   0x6000000e  d_ptr   Unspecified    Optional 
DT_SUNW_CAP    0x60000010  d_ptr   Optional    Optional 
DT_SUNW_SYMTAB   0x60000011  d_ptr   Optional    Optional 
DT_SUNW_SYMSZ   0x60000012  d_val   Optional    Optional 
DT_SUNW_ENCODING  0x60000013  Unspecified  Unspecified    Unspecified 
DT_SUNW_SORTENT   0x60000013  d_val   Optional    Optional 
DT_SUNW_SYMSORT   0x60000014  d_ptr   Optional    Optional 
DT_SUNW_SYMSORTSZ  0x60000015  d_val   Optional    Optional 
DT_SUNW_TLSSORT   0x60000016  d_ptr   Optional    Optional 
DT_SUNW_TLSSORTSZ  0x60000017  d_val   Optional    Optional 
DT_SUNW_CAPINFO   0x60000018  d_ptr   Optional    Optional 
DT_SUNW_STRPAD   0x60000019  d_val   Optional    Optional 
DT_SUNW_CAPCHAIN  0x6000001a  d_ptr   Optional    Optional 
DT_SUNW_LDMACH   0x6000001b  d_val   Optional    Optional 
DT_SUNW_CAPCHAINENT  0x6000001d  d_val   Optional    Optional 
DT_SUNW_CAPCHAINSZ  0x6000001f  d_val   Optional    Optional 
DT_HIOS     0x6ffff000  Unspecified  Unspecified    Unspecified 
DT_VALRNGLO    0x6ffffd00  Unspecified  Unspecified    Unspecified 
DT_CHECKSUM    0x6ffffdf8  d_val   Optional    Optional 
DT_PLTPADSZ    0x6ffffdf9  d_val   Optional    Optional 
DT_MOVEENT    0x6ffffdfa  d_val   Optional    Optional 
DT_MOVESZ    0x6ffffdfb  d_val   Optional    Optional 
DT_POSFLAG_1   0x6ffffdfd  d_val   Optional    Optional 
DT_SYMINSZ    0x6ffffdfe  d_val   Optional    Optional 
DT_SYMINENT    0x6ffffdff  d_val   Optional    Optional 
DT_VALRNGHI    0x6ffffdff  Unspecified  Unspecified    Unspecified 
DT_ADDRRNGLO   0x6ffffe00  Unspecified  Unspecified    Unspecified 
DT_CONFIG    0x6ffffefa  d_ptr   Optional    Optional 
DT_DEPAUDIT    0x6ffffefb  d_ptr   Optional    Optional 
DT_AUDIT    0x6ffffefc  d_ptr   Optional    Optional 
DT_PLTPAD    0x6ffffefd  d_ptr   Optional    Optional 
DT_MOVETAB    0x6ffffefe  d_ptr   Optional    Optional 
DT_SYMINFO    0x6ffffeff  d_ptr   Optional    Optional 
DT_ADDRRNGHI   0x6ffffeff  Unspecified  Unspecified    Unspecified 
DT_RELACOUNT   0x6ffffff9  d_val   Optional    Optional 
DT_RELCOUNT    0x6ffffffa  d_val   Optional    Optional 
DT_FLAGS_1    0x6ffffffb  d_val   Optional    Optional 
DT_VERDEF    0x6ffffffc  d_ptr   Optional    Optional 
DT_VERDEFNUM   0x6ffffffd  d_val   Optional    Optional 
DT_VERNEED    0x6ffffffe  d_ptr   Optional    Optional 
DT_VERNEEDNUM   0x6fffffff  d_val   Optional    Optional 
DT_LOPROC    0x70000000  Unspecified  Unspecified    Unspecified 
DT_SPARC_REGISTER  0x70000001  d_val   Optional    Optional 
DT_AUXILIARY   0x7ffffffd  d_val   Unspecified    Optional 
DT_USED     0x7ffffffe  d_val   Optional    Optional 
DT_FILTER    0x7fffffff  d_val   Unspecified    Optional 
DT_HIPROC    0x7fffffff  Unspecified  Unspecified    Unspecified 
+0

Große Antwort, vielen Dank! – crezefire