2016-07-08 17 views
0

Ich versuche strace zu verwenden, um zu verstehen, wie die Erlang VM writev verwendet. Ich weiß sehr wenig über Systemanrufe, und ich versuche zu verstehen, was ich sehe.Warum sehe ich in diesem Aufruf von `writev` keine Speicheradressen?

In this article zeigt der Autor ein Beispiel ein winziges Erlang Programm des Aufspürens, die in eine Datei schreibt, und einen Systemaufruf so zu sehen:

writev(0x1A, 0x1A5405F8, 0x4) 

Er fährt fort zu erklären, dass writev die gegeben wird Speicheradresse eines Vektors, der mehr Speicheradressen enthält. Vermutlich nimmt das Betriebssystem dann die Daten von diesen Adressen und legt sie in die Datei.

Ich habe versucht, dem Beispiel der Autor selbst - den gleichen Code in einem Elixir repl läuft iex genannt (in einer Ubunto 12.04 VM) und es so Tracing:

# show me system calls for process 1166... 
# ... and show long output if necessary (the -s flag) 
# ... and also trace any child processes (the -f flag) 
# ... and I only care about calls to writev (the -e flag) 
# ... and capture standard error to a file (the >(tee ...)) 
strace -p 1166 -s 99999 -f -e writev 2> >(tee syscalls.txt) 

Allerdings habe ich die Ausgabe bekam sieht wie folgt aus :

writev(11, [{"Hello ", 6}, {"&", 1}, {"amp;", 4}, {" Goodbye", 8}], 4) = 19 

lesen I dies als: "Deskriptor 11, schreiben die folgenden 4-Strings in Datei, jedes mit seiner Länge aufgeführt sind, in Höhe von insgesamt 19 Byte."

Aber warum sehe ich die tatsächlichen String-Werte anstelle der Speicheradressen? Bedeutet das, dass die Daten irgendwie kopiert werden, statt auf die Adresse zu verweisen, oder zeige ich sie einfach irgendwie falsch an?

Warum sehe ich keine Speicheradressen an writev, wenn ich diesen Prozess strace?

Antwort

1

strace wird immer besser. Anstatt sich eine ephemere Array-Adresse auszuloggen, teilt sie Ihnen nun mit, was geschrieben wurde und nützliche Informationen in Ihrem Log hinterlässt.

Sie können versuchen, mit den Flaggen futzing strace Flip-off Ausführlichkeit mit -e verbose=!writev - um vielleicht Zitat vorsichtig sein, benötigen und/oder die ! abhängig von der Shell zu entkommen - (wahrscheinlich, dass Sie nur die Adresse Ihres ephemeren Array zurückgeben, wie in dem von Ihnen zitierten Beispiel) und rotieren Sie das rohe Display mit -e raw=writev und sehen Sie, was Sie bekommen.

Sie könnten auch untersuchen, ob Sie einen Debugger anfügen und den Aufruf writev abfangen. Auf diese Weise können Sie herumstöbern und überprüfen, welche Daten vom Prozess an den Kernel gesendet werden. (Wenn Sie ein dynamisches Verfolgungswerkzeug wie dtrace zur Hand haben, würde Sie das auch ähnlich machen, aber ohne die Welt zu stoppen.)

+0

Awesome! Ja, ich erhalte die Speicheradressenausgabe mit 'strace -p 1166 -s 99999 -f -e 'ausführlich =! Writev' -e 'raw = writev' -e 'trace = writev' 2>> (tee syscalls.txt) ' –