Trace the system call

Strace is command to trace system calls and signals executed by process. Basically strace executes a command and intercepts, records system calls and signals executed and received by process.

It displays name of each system call, it’s arguments and exit value on standard error or in file name if specified. For more info see man page.

Let us take example of cat command to display contents of file.

$ strace cat hello.c
execve(“/bin/cat”, [“cat”, “hello.c”], [/* 43 vars */]) = 0
brk(0) = 0x84a2000
access(“/etc/ld.so.nohwcap”, F_OK) = -1 ENOENT (No such file or directory)

mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7701000
access(“/etc/ld.so.preload”, R_OK) = -1 ENOENT (No such file or directory)
open(“/etc/ld.so.cache”, O_RDONLY|O_CLOEXEC) = 3

fstat64(3, {st_mode=S_IFREG|0644, st_size=83151, …}) = 0
mmap2(NULL, 83151, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb76ec000
close(3) = 0
access(“/etc/ld.so.nohwcap”, F_OK) = -1 ENOENT (No such file or directory)

open(“/lib/i386-linux-gnu/libc.so.6”, O_RDONLY|O_CLOEXEC) = 3
read(3, “177ELF1113312202321004″…, 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1775080, …}) = 0

mmap2(NULL, 1784604, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7538000
mmap2(0xb76e6000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1ae) = 0xb76e6000
mmap2(0xb76e9000, 11036, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb76e9000

close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7537000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7537900, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0

mprotect(0xb76e6000, 8192, PROT_READ) = 0
mprotect(0x8053000, 4096, PROT_READ) = 0
mprotect(0xb7724000, 4096, PROT_READ) = 0
munmap(0xb76ec000, 83151) = 0
open(“/usr/lib/locale/locale-archive”, O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3

fstat64(3, {st_mode=S_IFREG|0644, st_size=8748544, …}) = 0
mmap2(NULL, 2097152, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7337000
mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0x5db) = 0xb7700000
brk(0) = 0x84a2000

brk(0x84c3000) = 0x84c3000
close(3) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), …}) = 0
open(“hello.c”, O_RDONLY|O_LARGEFILE) = 3

fstat64(3, {st_mode=S_IFREG|0664, st_size=74, …}) = 0
fadvise64_64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, “#include <stdio.h>nnint main () “…, 65536) = 74
write(1, “#include <stdio.h>nnint main () “…, 74#include <stdio.h>

int main () {
printf(“hello world n”);
return 0;
}
) = 74
read(3, “”, 65536) = 0
close(3) = 0
close(1) = 0

close(2) = 0
exit_group(0) = ?
$

If you look at each of the system call strace displayed, then you could know how operating system executes commands on behalf of user.

When we run cat command, execve system call is executed first start cat process. Then kernel loads required libraries libc etc. After that it opens and reads hello.c file writes it’s contents to standard output and exits.

This command is very useful while debugging or learning.

Enjoy!

Post a Comment

You must be logged in to post a comment.
%d bloggers like this: