Frage

OS X fehlt Linux strace, aber es hat dtrace, die so viel besser sein soll.

Allerdings vermisse ich die Möglichkeit, auf einzelne Befehle einfache Verfolgung zu tun. Zum Beispiel auf Linux kann ich schreiben strace -f gcc hello.c alle Systemaufrufe caputre, die mir die Liste der gibt alle die vom Compiler benötigten Dateinamen mein Programm (den ausgezeichneten memoize Skript auf diesen Trick gebaut wird)

Ich möchte Port memoize auf dem Mac, so dass ich eine Art von strace benötigen. Was ich wirklich brauchen, ist die Liste der Dateien gcc liest und schreibt in, also was ich brauche, ist eher ein truss. Sicher genug kann ich dtruss -f gcc hello.c sagen und etwas die gleiche Funktionalität, aber dann wird der Compiler mit Root-Privilegien ausführen, die von dem massiven Sicherheitsrisiko offensichtlich unerwünscht (abgesehen ist, ist ein Problem, dass die a.out Datei nun im Besitz von root ist :-)

ich dtruss -f sudo -u myusername gcc hello.c dann versucht, aber das fühlt sich ein bisschen falsch, und nicht funktioniert sowieso (ich keine a.out Datei auf die ganze Zeit bekommen, nicht sicher, warum)

Alles, was lange Geschichte versucht meine ursprüngliche Frage zu motivieren: wie bekomme ich dtrace meinen Befehl mit normalen Benutzerrechten ausführen, so wie strace unter Linux funktioniert

Edit: ist scheint, dass ich bin nicht der einzige, fragen, wie dies zu tun: Frage # 1204256 so ziemlich das gleiche wie mein (und hat die gleiche suboptimal sudo Antwort :-)

War es hilfreich?

Lösung

Nicht eine Antwort auf Ihre Frage, aber etwas zu wissen. Open löste dieses Problem (teilweise) mit „Privilegien“ - siehe diese Seite . Auch in Opensolaris, wäre es nicht möglich sein, einen Benutzer zu ermöglichen, ohne zusätzliche Privilegien, ihre eigenen Verfahren dtruss. Der Grund dafür ist die Art und Weise dtrace Werke - es Sonden in den Kernel ermöglicht. So ermöglicht eine nicht-privilegierten Benutzer Sonde Kernel bedeutet, dass der Benutzer viele unerwünschte Dinge tun kann, zum Beispiel Schnüffeln passwd des anderen Benutzers durch Sonden in Tastaturtreiber ermöglicht!

Andere Tipps

Der einfachste Weg ist die Verwendung von sudo:

sudo dtruss -f sudo -u $USER whoami

Andere Lösung wäre, den Debugger zuerst laufen und für neue spezifische Prozesse überwachen. Z.

sudo dtruss -fn whoami

Dann in einem anderen Terminal einfach auszuführen:

whoami

So einfach ist das.

Weitere knifflige Argumente, die Sie im Handbuch finden: man dtruss


Alternativ können Sie dtruss zur Lauf Benutzer Prozess anhängen z.B. Mac OS X:

sudo dtruss -fp PID

oder ähnliches unter Linux / Unix durch strace mit:

sudo strace -fp PID

Ein weiterer Hacky Trick könnte sein, den Befehl auszuführen und direkt nach, der zum Prozess anhängen. Hier sind einige Beispiele:

sudo true; (./Pages &); sudo dtruss -fp `pgrep -n -x Pages`
sudo true; (sleep 1 &); sudo dtruss -fp `pgrep -n -x sleep`
sudo true; (tail -f /var/log/system.log &); sudo dtruss -fp `pgrep -n -x tail`

Hinweis:

  • erster sudo ist nur für das Caching des Passwortes beim ersten Mal laufen,

  • Dieser Trick funktioniert nicht für die schnelle Befehlszeilen wie ls, date wie es dauert einige Zeit, bis Debugger an den Prozess anhängen wird,

  • Sie haben Ihren Befehl an zwei Stellen eingeben,

  • Sie können & ignorieren den Prozess in den Hintergrund zu laufen, wenn es bereits, das zu tun,

  • nach dem Debuggen Beenden Sie manuell den Hintergrundprozess töten müssen (z killall -v tail)

Das -n Argument dtruss verursacht dtruss auf Prozesse warten und untersuchen, um das Argument zu -n entsprechen. Die -f Option wird immer noch funktionieren Prozesse aus den Prozessen von -n abgestimmt gegabelt folgen.

All dies bedeutet, dass, wenn Sie einen Prozess dtruss wollen (aus Gründen der Argumentation, lassen Sie uns sagen, es ist whoami) als nicht-privilegierten Benutzer ausgeführt wird, gehen Sie folgendermaßen vor:

  1. Öffnen Sie eine Root-Shell
  2. Ausführen dtruss -fn whoami
    • das wird sitzen und für einen Prozess warten namens „whoami“ existieren
  3. öffnen Sie ein nicht-privilegiert Shell
  4. Ausführen whoami
    • wird dies ausführen und beenden normalerweise
  5. Beobachten Systemaufruf Spur in dtruss Fenster
    • dtruss wird nicht Ausfahrt auf seinem eigenen - es wird auch weiterhin für die Matching-Prozesse warten - so es auszubrechen wenn Sie fertig sind

Diese Antwort dupliziert den letzten Teil von @ kenorb Antwort, aber es verdient eine erstklassige Antwort zu sein.

Ich weiß nicht, ob Sie dtruss zu sein, wie nicht-invasive wie strace erhalten können.

Eine Variante des "sudo [root] dtruss sudo [zurück zu nonroot] cmd", die für mich in ein paar schnellen Tests besser funktionieren scheint, ist:

sudo dtruss -f su -l `whoami` cd `pwd` && cmd....

Die äußere sudo ist natürlich so dtruss läuft als root an.

Der innere su ist mir zurück, und mit -l neu erstellt die Umwelt richtig, an die wir auf CD wieder zeigen müssen, wo wir angefangen haben.

Ich denke, „su -l user“ ist besser als „sudo -u Benutzer“, wenn Sie die Umgebung sein wollen, was dieser Benutzer normalerweise bekommt. Das wird ihre Login-Umgebung sein, obwohl; Ich weiß nicht, ob es ein guter Weg, um die Umwelt erben zu lassen, durch die zwei Benutzer ändern statt.

In Ihrer Frage, eine weitere Beschwerde, dass Sie über die „sudo dtruss sudo“ Abhilfe hatte, anders als Hässlichkeit, war, dass „ich keine a.out Datei auf die ganze Zeit bekommen, nicht sicher, warum“. Ich weiß nicht, warum auch nicht, aber in meinem kleinen Test-Skript, eine „sudo dtruss sudo“ Variante auch zu schreiben, um eine Testausgabedatei nicht, und die „sudo dtruss su“ Variante über die Ausgabedatei haben erstellen.

Es scheint, dass OS X nicht DTrace unterstützt alle Funktionen von strace zu replizieren, die Sie benötigen. Ich würde jedoch vorschlagen, einen Wrapper um geeigneten syscalls zu schaffen versuchen. Es sieht aus wie DYLD_INSERT_LIBRARIES ist die Umgebungsvariable Sie ein wenig hacken wollen. Das ist im Grunde die gleichen wie LD_PRELOAD für Linux.

  

Eine viel einfachere Art und Weise Bibliotheksfunktion überschreibt zu tun, ist die Verwendung von   DYLD_INSERT_LIBRARIES Umgebungsvariable (analog zu LD_PRELOAD on   Linux). Das Konzept ist einfach: beim Laden der dynamischen Linker (dyld)   lädt in DYLD_INSERT_LIBRARIES angegeben alle dynamischen Bibliotheken   vor allen Bibliotheken geladen die ausführbaren will. Durch eine Funktion Namensgebung   das gleiche wie man in einer Bibliothek Funktion wird es keine Anrufe außer Kraft setzen zu   das Original.

     

Die ursprüngliche Funktion wird auch geladen und kann abgerufen wird die Verwendung von   dlsym (RTLD_NEXT „function_name“); Funktion. Dies ermöglicht eine einfache   bestehenden Bibliotheksfunktionen Methode der Verpackung.

Nach dem Beispiel von Tom Robinson Sie Satz DYLD_FORCE_FLAT_NAMESPACE=1 benötigen auch.

Kopie des ursprünglichen Beispiels (lib_overrides.c), dass Überschreibungen nur fopen:

#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>

// for caching the original fopen implementation
FILE * (*original_fopen) (const char *, const char *) = NULL;

// our fopen override implmentation
FILE * fopen(const char * filename, const char * mode)
{
    // if we haven’t already, retrieve the original fopen implementation
    if (!original_fopen)
        original_fopen = dlsym(RTLD_NEXT, "fopen");

    // do our own processing; in this case just print the parameters
    printf("== fopen: {%s,%s} ==\n", filename, mode);

    // call the original fopen with the same arugments
    FILE* f = original_fopen(filename, mode);

    // return the result
    return f;
}

Verbrauch:

$ gcc -Wall -o lib_overrides.dylib -dynamiclib lib_overrides.c
$ DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=lib_overrides.dylib command-to-test

Disclaimer: Dies ist abgeleitet von @ kenorb Antwort . Es hat einige Vorteile aber: PID-spezifischer als execname ist. Und wir können einen kurzlebigen Prozess warten, DTrace, bevor es beginnt.

Das ist ein bisschen Renn conditiony, aber ...

Lassen Sie uns sagen, dass wir auf Spuren cat /etc/hosts wollen:

sudo true && \
(sleep 1; cat /etc/hosts) &; \
sudo dtrace -n 'syscall:::entry /pid == $1/ {@[probefunc] = count();}' $!; \
kill $!

Wir verwenden sudo true sicher zu stellen, dass wir Passwort klare sudo Prompt, bevor wir anfangen zu laufen etwas zeitempfindlich.

Wir haben einen Hintergrundprozess starten ( „1 Sekunde warten, dann etwas Interessantes tun“). Inzwischen haben wir DTrace starten. Wir haben die Hintergrundprozess der PID in $! erfasst, so dass wir auf DTrace als arg passieren kann.

Die kill $! läuft nach schließen wir DTrace. Es ist nicht notwendig für unser cat Beispiel (Prozess schließt auf eigene), aber es hilft uns: Ende der laufenden Hintergrundprozesse wie ping. Vorbei -p $! zu DTrace ist der bevorzugte Weg, dies zu tun, aber auf macOS erfordert offenbar eine Code-signierte ausführbare.


Das andere, was Sie tun können, ist, den Befehl in einer separaten Schale laufen, und dass die Schale schnüffeln. Siehe meine Antwort .

Ich weiß nicht, einen Weg zu laufen, was man als normaler Benutzer wollen, wie es, dass dtruss scheint, die dtrace Privilegien su verwendet erfordert.

Ich glaube jedoch, der Befehl Sie statt der Suche wurden

dtruss -f sudo -u myusername gcc hello.c

ist

sudo dtruss -f gcc hello.c

Nach der Eingabe in Ihrem Kennwort ein, dtruss wird dtrace ausführen Privilegien sudo wird, und Sie erhalten die Spur sowie die a.out-Datei erhalten.

Leider habe ich nicht weiterhelfen könnte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top