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).

Justicle
quelle
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;
}
Angestellt Russisch
quelle
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.

Michael Dillon
quelle
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
12

Sie können auch verwenden:

chrpath -l binary-or-library
Oscar Andreasson
quelle
Auf Ubuntu:apt-get install -y chrpath
Toby Brull
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.

Craig Ringer
quelle