在 Linux system 底下,必須透過 GLIBC 裡的 system call function 來取得 kernel 的 system call 服務。
由 GLIBC 提供用來呼叫 system call 的函數稱為 wrapper function,wrapper function會呼叫 Linux kernel的handler routine,即 system_call() 函數。
呼叫 getpid() system call 的範例:
#include#include #include int main() { pid_t self, parent; self = getpid(); parent = getppid(); printf("PID: %d, Parent PID: %d\n", (int) self, (int) parent); return 0; }
利用 strace 工具可以追蹤程式所使用到的 system call:
$ strace ./pid execve("./pid", ["./pid"], [/* 25 vars */]) = 0 uname({sys="Linux", node="jollen", ...}) = 0 brk(0) = 0x80495ac old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40016000 open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=114793, ...}) = 0 old_mmap(NULL, 114793, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40017000 close(3) = 0 open("/lib/tls/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`V\1B4\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=1531064, ...}) = 0 old_mmap(0x42000000, 1257224, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x42000000 old_mmap(0x4212e000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x12e000) = 0x4212e000 old_mmap(0x42131000, 7944, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x42131000 close(3) = 0 set_thread_area({entry_number:-1 -> 6, base_addr:0x400169e0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 munmap(0x40017000, 114793) = 0 getpid() = 970 getppid() = 969 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40017000 write(1, "PID: 970, Parent PID: 969\n", 26) = 26 munmap(0x40017000, 4096) = 0 exit_group(0) = ?
由 strace 的輸出結果可以得知程式所呼叫的 system call,在這裡我們可以看到 getpid() 與 getppid(),並且也能得知 printf() 是基於 write() system call。
--jollen