autrace can log the system calls made by a program by running it. I want to log the system calls of already running programs. It can be done by finding the process id, but is there any other elegant way? Which may be using the chrome executable file as a parameter to log system calls generated by it?
2 Answers
As @Patrick stated in the comments, you can use the command line tool strace to produce a dump of the system calls that are made by a program as it runs.
Example
Here's an example showing the command echo hi being run.
$ strace echo "hi" execve("/usr/bin/echo", ["echo", "hi"], [/* 94 vars */]) = 0 brk(0) = 0xf73000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9996cf2000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=206010, ...}) = 0 mmap(NULL, 206010, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9996cbf000 close(3) = 0 open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\34\242\213?\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=2108632, ...}) = 0 mmap(0x3f8ba00000, 3932768, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3f8ba00000 mprotect(0x3f8bbb6000, 2097152, PROT_NONE) = 0 mmap(0x3f8bdb6000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b6000) = 0x3f8bdb6000 mmap(0x3f8bdbc000, 16992, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3f8bdbc000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9996cbe000 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9996cbc000 arch_prctl(ARCH_SET_FS, 0x7f9996cbc740) = 0 mprotect(0x606000, 4096, PROT_READ) = 0 mprotect(0x3f8bdb6000, 16384, PROT_READ) = 0 mprotect(0x3f8b820000, 4096, PROT_READ) = 0 munmap(0x7f9996cbf000, 206010) = 0 brk(0) = 0xf73000 brk(0xf94000) = 0xf94000 brk(0) = 0xf94000 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=106055264, ...}) = 0 mmap(NULL, 106055264, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9990797000 close(3) = 0 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9996cf1000 write(1, "hi\n", 3hi ) = 3 close(1) = 0 munmap(0x7f9996cf1000, 4096) = 0 close(2) = 0 exit_group(0) = ? +++ exited with 0 +++ You can also increase the details that get output by including the option -s <size>. I typically will use -s 2000 to get 2000 characters of output per call. Also I'll include the switch -o <file> to get the output to dump into a file. It's much easier to look at this output after the fact.
Example
$ strace -s 2000 -o strace.log echo "hi" hi And here's the file:
$ cat strace.log execve("/usr/bin/echo", ["echo", "hi"], [/* 94 vars */]) = 0 brk(0) = 0x1061000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f78bdab3000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=206010, ...}) = 0 mmap(NULL, 206010, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f78bda80000 close(3) = 0 open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\34\242\213?\0\0\0@\0\0\0\0\0\0\0\30\" \0\0\0\0\0\0\0\0\0@\0008\0\n\0@\0+\0*\0\6\0\0\0\5\0\0\0@\0\0\0\0\0\0\0@\0\240\213?\0\0\0@\0\240\213?\0\0\0000\2\0\0\0\0\0\0000\2\0\0\0\0\0\0\10\0\0\0\0\0\0\0\3\0\0\0\4\0\0\0\360\26\30\0\0\0\0\0\360\26\270\213?\0\0\0\360\26\270\213?\0\0\0\34\0\0\0\0\0\0\0\34\0\0\0\0\0\0\0\20\0\0\0\0\0\0\0\1\0\0\0\5\0\0\0\0\0\0\0\0\0\0\0\0\0\240\213?\0\0\0\0\0\240\213?\0\0\0\344W\33\0\0\0\0\0\344W\33\0\0\0\0\0\0\0 \0\0\0\0\0\1\0\0\0\6\0\0\0 g\33\0\0\0\0\0 g\333\213?\0\0\0 g\333\213?\0\0\0\240Q\0\0\0\0\0\0@\233\0\0\0\0\0\0\0\0 \0\0\0\0\0\2\0\0\0\6\0\0\0\200\233\33\0\0\0\0\0\200\233\333\213?\0\0\0\200\233\333\213?\0\0\0\360\1\0\0\0\0\0\0\360\1\0\0\0\0\0\0\10\0\0\0\0\0\0\0\4\0\0\0\4\0\0\0p\2\0\0\0\0\0\0p\2\240\213?\0\0\0p\2\240\213?\0\0\0D\0\0\0\0\0\0\0D\0\0\0\0\0\0\0\4\0\0\0\0\0\0\0\7\0\0\0\4\0\0\0 g\33\0\0\0\0\0 g\333\213?\0\0\0 g\333\213?\0\0\0\20\0\0\0\0\0\0\0\220\0\0\0\0\0\0\0\20\0\0\0\0\0\0\0P\345td\4\0\0\0\f\27\30\0\0\0\0\0\f\27\270\213?\0\0\0\f\27\270\213?\0\0\0\\h\0\0\0\0\0\0\\h\0\0\0\0\0\0\4\0\0\0\0\0\0\0Q\345td\6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\20\0\0\0\0\0\0\0R\345td\4\0\0\0 g\33\0\0\0\0\0 g\333\213?\0\0\0 g\333\213?\0\0\0\3408\0\0\0\0\0\0\3408\0\0\0\0\0\0\1\0\0\0\0\0\0\0\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\206\353)\243\237\22p\240\253\216F\316.Tkn\303R\312\10\4\0\0\0\20\0\0\0\1\0\0\0GNU\0\0\0\0\0\2\0\0\0\6\0\0\0 \0\0\0\0\0\0\0\363\3\0\0\t\0\0\0\0\1\0\0\16\0\0\0\0000\20D\240 \2\1\210\3\346\220\305E\214\0\300\0\10\0\5\200\0`\300\200\0\r\212\f\0\4\20\0\210D2\10.@\210P<, \0162H&\204\300\214\4\10\0\2\2\16\241\254\32\4f\300\0\3002\0\300\0P\1 \201\10\204\v ($\0\4 P\0\20X\200\312DB(\0\6\200\20\30B\0 @\200\0\tP\0Q\212@\20\0\0\0\0\10\0\0\21\20", 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=2108632, ...}) = 0 mmap(0x3f8ba00000, 3932768, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3f8ba00000 mprotect(0x3f8bbb6000, 2097152, PROT_NONE) = 0 mmap(0x3f8bdb6000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b6000) = 0x3f8bdb6000 mmap(0x3f8bdbc000, 16992, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3f8bdbc000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f78bda7f000 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f78bda7d000 arch_prctl(ARCH_SET_FS, 0x7f78bda7d740) = 0 mprotect(0x606000, 4096, PROT_READ) = 0 mprotect(0x3f8bdb6000, 16384, PROT_READ) = 0 mprotect(0x3f8b820000, 4096, PROT_READ) = 0 munmap(0x7f78bda80000, 206010) = 0 brk(0) = 0x1061000 brk(0x1082000) = 0x1082000 brk(0) = 0x1082000 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=106055264, ...}) = 0 mmap(NULL, 106055264, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f78b7558000 close(3) = 0 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f78bdab2000 write(1, "hi\n", 3) = 3 close(1) = 0 munmap(0x7f78bdab2000, 4096) = 0 close(2) = 0 exit_group(0) = ? +++ exited with 0 +++ You can include any program or command that you can typically run in your shell as an argument to strace. It's probably the most useful tool included with Linux in terms of gaining insights into how executables work within your system.
I'm only scratching the surface here, you can instruct strace to only show system calls or signals too. Check out the man strace page for more info.
Addressing the question:
I want to log the system calls of already running programs.
strace can start a program by name, but for "already running programs", you must (as in autrace) refer to the process-id.
A given executable can have multiple processes associated with it. You could make a script which checks all of the exe links under /proc, e.g.,
/proc/*/exe to see which match the executable that you're interested in, and (since the intermediate directory name is the process id) make strace run for each of those processes.
For any process that you can trace, the exe link is the pathname of an executable. Your script would read the pathname (using readlink) and if it matches, run strace with the -p option for the corresponding process id. Of course, you would run those in the background, to be able to handle multiple processes.
Collecting those together into a coherent logfile might (or might not) be what you want to do next. Your script could pipe the results from strace to logger, making the result one big logfile.
Further reading:
- proc - process information pseudo-filesystem, explains
/proc/[pid]/exe - Bash Shell Script - Write to Custom Log file
- Shell scripting: Write message to a syslog / log file
as well as the manual pages:
strace? - "trace system calls and signals"