Reputation: 126072
I'm trying to use strace
to understand how the Erlang VM uses writev
. I know very little about system calls, and I'm trying to understand what I'm seeing.
In this article, the author shows an example of tracing a tiny Erlang program which writes to a file, and seeing a system call like this:
writev(0x1A, 0x1A5405F8, 0x4)
He goes on to explain that writev
is being given the memory address of a vector, which contains some more memory addresses. Presumably the operating system then takes the data from those addresses and puts it in the file.
I tried the author's example myself - running the same code in an Elixir repl called iex
(in an Ubunto 12.04 VM) and tracing it like this:
# 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)
However, the output I got looks like this:
writev(11, [{"Hello ", 6}, {"&", 1}, {"amp;", 4}, {" Goodbye", 8}], 4) = 19
I read this as: "to file descriptor 11, write the following 4 strings, each listed with its length, totaling 19 bytes."
But why do I see the actual string values instead of the memory addresses? Does it imply the data is being somehow copied instead of referenced by address, or am I simply displaying it wrong somehow?
Why don't I see memory addresses being given to writev
when I strace
this process?
Upvotes: 0
Views: 608
Reputation: 36143
strace keeps getting better. Now, instead of logging out an ephemeral array address, it actually tells you what was being written, which leaves useful information in your log.
You can try futzing with the flags to strace to flip off verbosity with -e verbose=!writev
– be careful about needing to maybe quote and/or escape the !
depending on your shell – (likely will just give you back your ephemeral array address, as in the example you quoted) and flip on raw display with -e raw=writev
and see what you get.
You could also investigate attaching a debugger and intercepting the writev
call. This would let you poke around and inspect the data getting sent to the kernel from the process. (If you have a dynamic tracing utility like dtrace
at hand, that would also let you do similar, though without stopping the world.)
Upvotes: 1