Gibt es eine Möglichkeit, den aktuellen Pfad unter Linux zu überprüfen?


82

Ich bin mir bewusst, dass es möglich ist, readelf -d <elf> | grep RPATHeine bestimmte Binärdatei von der Shell aus zu untersuchen, aber ist es möglich, dies innerhalb eines Prozesses zu tun?

So etwas wie (mein komplett erfundener Systemaufruf):

  /* get a copy of current rpath into buffer */
  sys_get_current_rpath(&buffer);

Ich versuche, einige verdächtige SO-Verknüpfungsprobleme in unserer Codebasis zu diagnostizieren, und möchte den RPATH nach Möglichkeit auf diese Weise überprüfen (ich möchte lieber kein externes Skript erstellen).


1
Beachten Sie, dass Sie bei der Diagnose von Problemen mit gemeinsam genutzten Bibliotheken auch das RUNPATH-Tag überprüfen sollten. Also solltest du grep PATHstattdessen. Es liegt am Linker, ob RPATH oder RUNPATH verwendet wird, und es gibt subtile, aber wichtige Unterschiede zwischen den beiden: stackoverflow.com/a/52020177
— Nicolas Capens

Antworten:


54
#include <stdio.h>
#include <elf.h>
#include <link.h>

int main()
{
  const ElfW(Dyn) *dyn = _DYNAMIC;
  const ElfW(Dyn) *rpath = NULL;
  const char *strtab = NULL;
  for (; dyn->d_tag != DT_NULL; ++dyn) {
    if (dyn->d_tag == DT_RPATH) {
      rpath = dyn;
    } else if (dyn->d_tag == DT_STRTAB) {
      strtab = (const char *)dyn->d_un.d_val;
    }
  }

  if (strtab != NULL && rpath != NULL) {
    printf("RPATH: %s\n", strtab + rpath->d_un.d_val);
  }
  return 0;
}

1
es ist brillant, aber es funktioniert nicht mit $ ORIGIN. $ ORIGIN wird nicht interpretiert und von der Funktion unverändert zurückgegeben. Gibt es eine Möglichkeit, die $ ORIGIN-Interpretation hinzuzufügen?
— Jérôme

5
@ Jérôme Wenn Sie in einer Umgebung ausgeführt werden, in der /procgemountet ist, ist das Erweitern $ORIGINso einfach wie das readlink("/proc/self/exe", ...)NUL-Beenden beim letzten Schrägstrich.
— Angestellt Russisch

Während die Frage speziell war RPATH, möchte ich darauf hinweisen, dass es ebenso wichtig ist, das DT_RUNPATHTag zu überprüfen, wenn man wissen möchte, aus welchen Pfaden eine Binärdatei ihre gemeinsam genutzten Bibliotheken laden könnte.
— Nicolas Capens

153

Für die Aufzeichnung sind hier einige Befehle, die den rpathHeader anzeigen.

objdump -x binary-or-library |grep RPATH

Vielleicht ist der folgende Weg noch besser:

readelf -d binary-or-library |head -20

Der zweite Befehl listet auch die direkten Abhängigkeiten von anderen Bibliotheken auf, gefolgt von rpath.


7
Auf Ubuntu 15.04 muss ich verwenden: objdump -x Binär-oder-Bibliothek | grep RUNPATH
— Andreas Roth


11
Diese Antwort hat nichts mit der Frage zu tun , die gestellt wurde (und enthielt in der Frage selbst).
— Angestellt Russisch


1

Folgendes verwende ich der Einfachheit halber als Shell-Funktion:

function getrpath {
    eu-readelf -d "${1:?}" | sed -e '/RUNPATH/{s~.*\[\(.*\)\]~\1~;n};d'
}

Dies verbraucht eu-readelfAusgabe von elfutilswie:

Type              Value
NEEDED            Shared library: [libpq.so.5]
NEEDED            Shared library: [libc.so.6]
RUNPATH           Library runpath: [/some/path/to/lib]
....

und emittiert

 /some/path/to/lib

Es sollte auch mit Binutils readelfanstelle von Elfutils gut funktionieren eu-readelf.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.