I think all those syscalls are just the dynamic linker setting up stuff before execution. I made a little test program to check this out.
me@bar:~/foo$ cat main.c
#include <unistd.h>
void main(){
syscall(60,0);
}
now we compile it first statically and then dynamically.
the -Wl,-emain
argument tells gcc to pass -emain
to the linker, that means set main
as the entry point. And sure enough the program exits immediately.
me@bar:~/foo$ gcc -static main.c -Wl,-emain -o main
me@bar:~/foo$ strace ./main 2>&1 | head
execve("./main", ["./main"], 0x7fff6d7c4b40 /* 50 vars */) = 0
exit(0) = ?
+++ exited with 0 +++
now without the -static
flag, we get what you usually see.
me@bar:~/foo$ gcc main.c -Wl,-emain -o main
me@bar:~/foo$ strace ./main 2>&1 | head
execve("./main", ["./main"], 0x7fff06b48d20 /* 50 vars */) = 0
brk(NULL) = 0x558c61a90000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffd68e8e950) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=77239, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 77239, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe55ed7e000
...
Even though the code is meant to jump directly to main
!
now I thought that might be specific to libc, maybe it needs to set itself up or something like that. but actually its not, I tried making a little dynamic library to link with, and then on the strace the following showed up:
$ ldd main
linux-vdso.so.1 (0x00007fff9c8cd000)
libfoo.so => /home/me/path/to/libfoo.so (0x00007f80ed20a000)
$ strace ./main
execve("./main", ["./main"], 0x7ffcdf5b5a70 /* 51 vars */) = 0
brk(NULL)
...
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/me/path/to/libfoo.so", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=13240, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f028541c000
mmap(NULL, 16384, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f0285418000
mmap(0x7f0285419000, 4096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x7f0285419000
mmap(0x7f028541a000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f028541a000
mmap(0x7f028541b000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f028541b000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f028541d040) = 0
set_tid_address(0x7f028541d310) = 6310
set_robust_list(0x7f028541d320, 24) = 0
rseq(0x7f028541d960, 0x20, 0, 0x53053053) = 0
mprotect(0x7f028541b000, 4096, PROT_READ) = 0
mprotect(0x402000, 4096, PROT_READ) = 0
exit(0) = ?
+++ exited with 0 +++
I'm not sure what most of the calls there are doing, but its pretty clear they are just mapping my little libfoo
(actually a single function that just executes the exit syscall) in memory. So these traces are clearly from the dynamic linker, mapping the dynamic library into memory (after opening it on filedescriptor 3) and then handing over execution to the program proper (which in this case is merely exiting immediately).
Now, i guess the brk
call is there because the dynamic linker needs to work out the memory layout the program will have during runtime, so it needs to do some math with that value. Linux being free software, this is probably explained somewhere in the source for the dynamic linker.
Hope this helps.
brk(0)
actually just checks the current break, it doesn't change it yet. – ilkkachu Aug 27 '18 at 08:38brk(NULL)
is the 2nd system call. Well I just realized it is not always the 2nd systemcall. When I runstrace ping google.com
, I getaccess("/etc/suid-debug", F_OK) = -1 ENOENT (No such file or directory)
as a 2nd call afterexecve
– MaverickD Aug 29 '18 at 00:48strace
does not register the invocation of thefork()
call, that it is made by the parent process andstrace
only tracks what the child does ? Also in this case, the parent process would simply be the shell right ? – First User Aug 05 '22 at 14:10