[[PageOutline]] = 10/05 = == trace getpid() syscall with GDB == * windell57:x86_64 s0711489$ gdb {{{ (gdb) set logging file gdb.getpid.log (gdb) set logging on Copying output to gdb.getpid.log. (gdb) file vmlinux Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done. (gdb) b sys_getpid Breakpoint 1 at 0xffffffff81048ce4: file kernel/timer.c, line 1344. (gdb) target remote localhost:8864 Remote debugging using localhost:8864 0xffffffff810097a9 in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49 49 asm volatile("sti; hlt": : :"memory"); (gdb) c Continuing. Breakpoint 1, sys_getpid () at kernel/timer.c:1344 }}} * => attachment:gdb.getpid.log * on VM guest * s0711489@ubuntu-lucid64:~/coursework/KernelHack/02$ ./getpid {{{ getpid() -> 2143 }}} == trace log with source list and print data == * windell57:x86_64 s0711489$ gdb {{{ (gdb) file vmlinux Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done. (gdb) b sys_getpid Breakpoint 1 at 0xffffffff81048ce4: file kernel/timer.c, line 1344. (gdb) target remote localhost:8864 Remote debugging using localhost:8864 0xffffffff810097a9 in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49 49 asm volatile("sti; hlt": : :"memory"); (gdb) c Continuing. Breakpoint 1, sys_getpid () at kernel/timer.c:1344 1344 { (gdb) bt #0 sys_getpid () at kernel/timer.c:1344 #1 0xffffffff810029eb in ?? () #2 0x0000000000000246 in ?? () #3 0x00007fff70d418e0 in ?? () #4 0x00007f6c11b19210 in ?? () #5 0x00007f6c11b05300 in ?? () #6 0x0000000000000027 in ?? () #7 0x0000000000000000 in ?? () (gdb) l 1339 * which case the tgid is the same in all threads of the same group. 1340 * 1341 * This is SMP safe as current->tgid does not change. 1342 */ 1343 SYSCALL_DEFINE0(getpid) 1344 { 1345 return task_tgid_vnr(current); 1346 } 1347 1348 /* (gdb) s 1345 return task_tgid_vnr(current); (gdb) get_current () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14 14 return percpu_read_stable(current_task); (gdb) l 9 10 DECLARE_PER_CPU(struct task_struct *, current_task); 11 12 static __always_inline struct task_struct *get_current(void) 13 { 14 return percpu_read_stable(current_task); 15 } 16 17 #define current get_current() 18 (gdb) bt #0 get_current () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14 #1 sys_getpid () at kernel/timer.c:1345 #2 0xffffffff810029eb in ?? () #3 0x0000000000000246 in ?? () #4 0x00007fff63204890 in ?? () #5 0x00007fc615a98210 in ?? () #6 0x00007fc615a84300 in ?? () #7 0x0000000000000027 in ?? () #8 0x0000000000000000 in ?? () (gdb) p current_task Cannot access memory at address 0xb540 (gdb) ptype current_task type = struct task_struct { (snip) (gdb) s sys_getpid () at kernel/timer.c:1344 1344 { (gdb) l 1339 * which case the tgid is the same in all threads of the same group. 1340 * 1341 * This is SMP safe as current->tgid does not change. 1342 */ 1343 SYSCALL_DEFINE0(getpid) 1344 { 1345 return task_tgid_vnr(current); 1346 } 1347 1348 /* (gdb) bt #0 sys_getpid () at kernel/timer.c:1344 #1 0xffffffff810029eb in ?? () #2 0x0000000000000246 in ?? () #3 0x00007fff63204890 in ?? () #4 0x00007fc615a98210 in ?? () #5 0x00007fc615a84300 in ?? () #6 0x0000000000000027 in ?? () #7 0x0000000000000000 in ?? () (gdb) s 1345 return task_tgid_vnr(current); (gdb) s task_tgid_vnr (tsk=0xffff88001bbe5880) at include/linux/sched.h:1606 1606 { (gdb) l 1601 } 1602 1603 pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); 1604 1605 static inline pid_t task_tgid_vnr(struct task_struct *tsk) 1606 { 1607 return pid_vnr(task_tgid(tsk)); 1608 } 1609 1610 (gdb) bt #0 task_tgid_vnr (tsk=0xffff88001bbe5880) at include/linux/sched.h:1606 #1 0xffffffff81048cf6 in sys_getpid () at kernel/timer.c:1345 #2 0xffffffff810029eb in ?? () #3 0x0000000000000246 in ?? () #4 0x00007fff63204890 in ?? () #5 0x00007fc615a98210 in ?? () #6 0x00007fc615a84300 in ?? () #7 0x0000000000000027 in ?? () #8 0x0000000000000000 in ?? () (gdb) p tsk $2 = (struct task_struct *) 0xffff88001bbe5880 (gdb) ptype tsk type = struct task_struct { (snip) pid_t pid; pid_t tgid; (snip) struct task_struct *group_leader; struct list_head ptraced; struct list_head ptrace_entry; struct pid_link pids[3]; (snip) (gdb) ptype tsk->group_leader->pids type = struct pid_link { struct hlist_node node; struct pid *pid; } [3] (snip) (gdb) s 1607 return pid_vnr(task_tgid(tsk)); (gdb) 1606 { (gdb) 1607 return pid_vnr(task_tgid(tsk)); (gdb) pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:444 444 { (gdb) bt #0 pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:444 #1 0xffffffff81048783 in task_tgid_vnr (tsk=) at include/linux/sched.h:1607 #2 0xffffffff81048cf6 in sys_getpid () at kernel/timer.c:1345 #3 0xffffffff810029eb in ?? () #4 0x0000000000000246 in ?? () #5 0x00007fff63204890 in ?? () #6 0x00007fc615a98210 in ?? () #7 0x00007fc615a84300 in ?? () #8 0x0000000000000027 in ?? () #9 0x0000000000000000 in ?? () (gdb) l 439 } 440 return nr; 441 } 442 443 pid_t pid_vnr(struct pid *pid) 444 { 445 return pid_nr_ns(pid, current->nsproxy->pid_ns); 446 } 447 EXPORT_SYMBOL_GPL(pid_vnr); 448 (gdb) ptype pid type = struct pid { atomic_t count; unsigned int level; struct hlist_head tasks[3]; struct rcu_head rcu; struct upid numbers[1]; } * (gdb) up #1 0xffffffff81048783 in task_tgid_vnr (tsk=) at include/linux/sched.h:1607 1607 return pid_vnr(task_tgid(tsk)); (gdb) ptype tsk->nsproxy->pid_ns type = struct pid_namespace { struct kref kref; struct pidmap pidmap[128]; int last_pid; struct task_struct *child_reaper; struct kmem_cache *pid_cachep; unsigned int level; struct pid_namespace *parent; struct vfsmount *proc_mnt; struct bsd_acct_struct *bacct; } * (gdb) down #0 pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:444 444 { (gdb) s 445 return pid_nr_ns(pid, current->nsproxy->pid_ns); (gdb) get_current (pid=0xffff88001fb55400) at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14 14 return percpu_read_stable(current_task); (gdb) p current_task Cannot access memory at address 0xb540 (gdb) s pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:445 445 return pid_nr_ns(pid, current->nsproxy->pid_ns); (gdb) s 444 { (gdb) 445 return pid_nr_ns(pid, current->nsproxy->pid_ns); (gdb) pid_nr_ns (pid=0xffff88001fb55400, ns=0xffffffff8181bfe0) at kernel/pid.c:431 431 { (gdb) bt #0 pid_nr_ns (pid=0xffff88001fb55400, ns=0xffffffff8181bfe0) at kernel/pid.c:431 #1 0xffffffff81052db6 in pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:445 #2 0xffffffff81048783 in task_tgid_vnr (tsk=) at include/linux/sched.h:1607 #3 0xffffffff81048cf6 in sys_getpid () at kernel/timer.c:1345 #4 0xffffffff810029eb in ?? () #5 0x0000000000000246 in ?? () #6 0x00007fff63204890 in ?? () #7 0x00007fc615a98210 in ?? () #8 0x00007fc615a84300 in ?? () #9 0x0000000000000027 in ?? () #10 0x0000000000000000 in ?? () (gdb) l 426 return pid; 427 } 428 EXPORT_SYMBOL_GPL(find_get_pid); 429 430 pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) 431 { 432 struct upid *upid; 433 pid_t nr = 0; 434 435 if (pid && ns->level <= pid->level) { (gdb) l 436 upid = &pid->numbers[ns->level]; 437 if (upid->ns == ns) 438 nr = upid->nr; 439 } 440 return nr; 441 } 442 443 pid_t pid_vnr(struct pid *pid) 444 { 445 return pid_nr_ns(pid, current->nsproxy->pid_ns); (gdb) ptype pid type = struct pid { atomic_t count; unsigned int level; struct hlist_head tasks[3]; struct rcu_head rcu; struct upid numbers[1]; } * (gdb) ptype ns type = struct pid_namespace { struct kref kref; struct pidmap pidmap[128]; int last_pid; struct task_struct *child_reaper; struct kmem_cache *pid_cachep; unsigned int level; struct pid_namespace *parent; struct vfsmount *proc_mnt; struct bsd_acct_struct *bacct; } * type = struct upid { int nr; struct pid_namespace *ns; struct hlist_node pid_chain; } * (gdb) ptype pid_t type = int (gdb) p ns->level $5 = 0 (gdb) p pid->level $6 = 0 (gdb) p ns->level <= pid->level $7 = 1 (gdb) p ns $8 = (struct pid_namespace *) 0xffffffff8181bfe0 (gdb) p &pid->numbers[ns->level] $9 = (struct upid *) 0xffff88001fb55430 (gdb) p (&pid->numbers[ns->level])->ns $10 = (struct pid_namespace *) 0xffffffff8181bfe0 (gdb) info locals upid = nr = (gdb) p nr $11 = (gdb) p (&pid->numbers[ns->level])->nr $12 = 2225 (gdb) s 435 if (pid && ns->level <= pid->level) { (gdb) 431 { (gdb) 435 if (pid && ns->level <= pid->level) { (gdb) 436 upid = &pid->numbers[ns->level]; (gdb) 437 if (upid->ns == ns) (gdb) p upid $13 = (struct upid *) 0xffff88001fb55430 (gdb) s 438 nr = upid->nr; (gdb) p upid->ns == ns $14 = 1 (gdb) p nr $15 = (gdb) p upid->nr $16 = 2225 (gdb) s 441 } (gdb) pid_vnr (pid=) at kernel/pid.c:446 446 } (gdb) s task_tgid_vnr (tsk=) at include/linux/sched.h:1608 1608 } (gdb) sys_getpid () at kernel/timer.c:1346 1346 } (gdb) sys_getpid () at kernel/timer.c:1345 1345 return task_tgid_vnr(current); (gdb) sys_getpid () at kernel/timer.c:1346 1346 } (gdb) }}} * on VM guest * s0711489@ubuntu-lucid64:~/coursework/KernelHack/02$ ./getpid {{{ getpid() -> 2225 }}} === location of functions on source file === * windell57:x86_64 s0711489$ grep percpu_read_stable -r . {{{ (snip) ./arch/x86/include/asm/percpu.h:#define percpu_read_stable(var) percpu_from_op("mov", var, "p" (&(var))) (snip) }}} * windell57:x86_64 s0711489$ grep task_tgid -r . {{{ (snip) ./include/linux/sched.h:static inline struct pid *task_tgid(struct task_struct *task) (snip) }}} * include/linux/sched.h {{{ static inline struct pid *task_tgid(struct task_struct *task) { return task->group_leader->pids[PIDTYPE_PID].pid; } }}} === get_current function === * windell57:02 s0711489$ gcc -E ../linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h -I ~/coursework/KernelHack/linux-2.6.35.14/x86_64/include -I ~/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/ > current.h {{{ In file included from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/percpu.h:44, from ../linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:5: /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/include/linux/kernel.h:733:2: warning: #warning Attempt to use kernel headers from user space, see http: }}} * pre-processed arch/x86/include/asm/current.h {{{ static __always_inline struct task_struct *get_current(void) { return ({ typeof(current_task) pfo_ret__; switch (sizeof(current_task)) { case 1: asm("mov" "b ""%P" "1"",%0" : "=q" (pfo_ret__) : "p" (&(current_task))); break; case 2: asm("mov" "w ""%P" "1"",%0" : "=r" (pfo_ret__) : "p" (&(current_task))); break; case 4: asm("mov" "l ""%P" "1"",%0" : "=r" (pfo_ret__) : "p" (&(current_task))); break; case 8: asm("mov" "q ""%P" "1"",%0" : "=r" (pfo_ret__) : "p" (&(current_task))); break; default: __bad_percpu_size(); } pfo_ret__; }); } }}} = 10/12 = == tee system call == * http://linuxjm.sourceforge.jp/html/LDP_man-pages/man2/tee.2.html > {{{#!cc > #define _GNU_SOURCE > #include > #include > #include > #include > #include > #include > > int > main(int argc, char *argv[]) > { > int fd; > int len, slen; > > if (argc != 2) { > fprintf(stderr, "Usage: %s \n", argv[0]); > exit(EXIT_FAILURE); > } > > fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644); > if (fd == -1) { > perror("open"); > exit(EXIT_FAILURE); > } > > do { > /* > * tee stdin to stdout. > */ > len = tee(STDIN_FILENO, STDOUT_FILENO, > INT_MAX, SPLICE_F_NONBLOCK); > > if (len < 0) { > if (errno == EAGAIN) > continue; > perror("tee"); > exit(EXIT_FAILURE); > } else > if (len == 0) > break; > > /* > * Consume stdin by splicing it to a file. > */ > while (len > 0) { > slen = splice(STDIN_FILENO, NULL, fd, NULL, > len, SPLICE_F_MOVE); > if (slen < 0) { > perror("splice"); > break; > } > len -= slen; > } > } while (1); > > close(fd); > exit(EXIT_SUCCESS); > } > }}} * Ubuntu lucid(2.6.32-33-generic)やvanilla 2.6.35.14ではサンプルコードのまま正常に使える * mitty@ubuntu64:~/coursework/KernelHack/02$ cat tee.c | ./tee hoge | wc {{{ 58 130 1217 }}} * CentOS 5.7(2.6.18-238.19.1.el5.centos.plusPAE or 2.6.18-274.3.1.el5)ではspliceがエラーになる * viola01:02 s0711489$ cat tee.c | ./tee hoge | wc {{{ viola01:02 s0711489$ cat tee.c | ./tee hoge | wc splice: Invalid argument splice: Invalid argument splice: Invalid argument splice: Invalid argument splice: Invalid argument splice: Invalid argument splice: Invalid argument splice: Invalid argument splice: Invalid argument .... }}} * Ubuntu上でも、strace出来ない * mitty@ubuntu64:~/coursework/KernelHack/02$ strace -f -o sh.log sh -c 'cat tee.c | ./tee hoge | wc' * mitty@ubuntu64:~/coursework/KernelHack/02$ less sh.log {{{ (snip) 1611 <... tee resumed> ) = -1 EAGAIN (Resource temporarily unavailable) 1611 tee(0, 0x1, 0x7fffffff, 0x2) = -1 EAGAIN (Resource temporarily unavailable) 1611 tee(0, 0x1, 0x7fffffff, 0x2) = -1 EAGAIN (Resource temporarily unavailable) 1611 tee(0, 0x1, 0x7fffffff, 0x2) = -1 EAGAIN (Resource temporarily unavailable) 1611 tee(0, 0x1, 0x7fffffff, 0x2) = -1 EAGAIN (Resource temporarily unavailable) 1611 tee(0, 0x1, 0x7fffffff, 0x2) = -1 EAGAIN (Resource temporarily unavailable) 1611 tee(0, 0x1, 0x7fffffff, 0x2) = -1 EAGAIN (Resource temporarily unavailable) (snip) }}} * GDBによるステップ実行は、3000行ほど実行してみたがguest側で結果が出力されないので、断念 = 10/14 = == getcpu system call == * http://www.kernel.org/doc/man-pages/online/pages/man2/getcpu.2.html * http://www.linuxquestions.org/questions/programming-9/determine-what-cpu-my-thread-is-on-817697/ * getcpu system callはには存在しない * arch/x86/include/asm/unistd_64.h {{{#!cc #define __IGNORE_getcpu /* implemented as a vsyscall */ }}} * s0711489@ubuntu-lucid64:~/coursework/KernelHack/02$ cat > getcpu.c {{{#!cc #define _GNU_SOURCE /* See feature_test_macros(7) */ #include #include int main (void) { int c, s; s = getcpu(&c, NULL, NULL); printf ("getcpu() -> %d\n", (s == -1) ? s : c); } }}} * s0711489@ubuntu-lucid64:~/coursework/KernelHack/02$ gcc getcpu.c -o getcpu {{{ getcpu.c:1:26: error: linux/getcpu.h: No such file or directory }}} === i386 === * s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh {{{ + cat /mnt/hgfs/linux-2.6.35.14/include/config/kernel.release + VERSION=2.6.35.14 + echo Install Linux Kernel version 2.6.35.14 Install Linux Kernel version 2.6.35.14 + cd /mnt/hgfs/linux-2.6.35.14/ + make install sh /mnt/hgfs/linux-2.6.35.14/arch/x86/boot/install.sh 2.6.35.14 arch/x86/boot/bzImage \ System.map "/boot" + make modules_install INSTALL arch/x86/kernel/test_nx.ko INSTALL drivers/scsi/scsi_wait_scan.ko INSTALL net/netfilter/xt_mark.ko DEPMOD 2.6.35.14 + mkinitramfs -o /boot/initrd.img-2.6.35.14 2.6.35.14 + update-grub Generating grub.cfg ... Found linux image: /boot/vmlinuz-2.6.35.14 Found initrd image: /boot/initrd.img-2.6.35.14 Found linux image: /boot/vmlinuz-2.6.32-33-generic Found initrd image: /boot/initrd.img-2.6.32-33-generic Found memtest86+ image: /boot/memtest86+.bin done + echo Install Kernel Headers to /lib/modules/2.6.35.14/build Install Kernel Headers to /lib/modules/2.6.35.14/build + date +%Y%m%d + mv /lib/modules/2.6.35.14/build /lib/modules/2.6.35.14/build-20111014 + cd /mnt/hgfs/ + tar c --files-from - + tar x -C /lib/modules/2.6.35.14/ + egrep -v vmlinu + egrep -v .o$ + find linux-2.6.35.14 -type f + mv /lib/modules/2.6.35.14/linux-2.6.35.14 /lib/modules/2.6.35.14/build + uname -a Linux ubuntu-lucid 2.6.32-33-generic #72-Ubuntu SMP Fri Jul 29 21:08:37 UTC 2011 i686 GNU/Linux }}} * s0711489@ubuntu-lucid:~$ sudo vmware-config-tools.pl --default * s0711489@ubuntu-lucid:~$ cat > getcpu.c {{{#!cc #define _GNU_SOURCE #include #include #include #include #include int main( void ) { int cpu = syscall(SYS_getcpu); if (cpu < 0) { printf( "Error: errno = %d\n", errno ); fflush(stdout); printf( "Error: errno: %s\n", strerror(errno) ); fflush(stdout); return -1; } printf( "cpu = %d\n", cpu ); return 0; } }}} * s0711489@ubuntu-lucid:~$ gcc getcpu.c -o getcpu * s0711489@ubuntu-lucid:~$ ./getcpu {{{ Error: errno = 14 Error: errno: Bad address }}} * うまく動かない == getuid system call == * windell57:x86_64 s0711489$ gdb {{{ (gdb) set logging file gdb.getuid.log (gdb) set logging on Copying output to gdb.getuid.log. (gdb) file vmlinux Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done. (gdb) b sys_getuid Breakpoint 1 at 0xffffffff81048d17: file kernel/timer.c, line 1366. (gdb) target remote localhost:8864 Remote debugging using localhost:8864 0xffffffff810097a9 in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49 49 asm volatile("sti; hlt": : :"memory"); (gdb) c Continuing. Breakpoint 1, sys_getuid () at kernel/timer.c:1366 1366 { (gdb) s 1368 return current_uid(); (gdb) get_current () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14 14 return percpu_read_stable(current_task); (gdb) 1368 return current_uid(); (gdb) sys_getuid () at kernel/timer.c:1366 1366 { (gdb) 1368 return current_uid(); (gdb) get_current () at kernel/timer.c:1368 1368 return current_uid(); (gdb) sys_getuid () at kernel/timer.c:1369 1369 } (gdb) Program received signal SIGINT, Interrupt. 0xffffffff810097a9 in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49 49 asm volatile("sti; hlt": : :"memory"); (gdb) detach Ending remote debugging. (gdb) quit }}} * s0711489@ubuntu-lucid64:~/coursework/KernelHack/02$ ./getuid {{{ getuid() -> 1000 }}} === trace log with source list and print data === * windell57:x86_64 s0711489$ gdb {{{ (gdb) file vmlinux Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done. (gdb) b sys_getuid Breakpoint 1 at 0xffffffff81048d17: file kernel/timer.c, line 1366. (gdb) target remote localhost:8864 Remote debugging using localhost:8864 0xffffffff810097a9 in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49 49 asm volatile("sti; hlt": : :"memory"); (gdb) c Continuing. Breakpoint 1, sys_getuid () at kernel/timer.c:1366 1366 { (gdb) bt #0 sys_getuid () at kernel/timer.c:1366 #1 0xffffffff810029eb in ?? () #2 0x0000000000000206 in ?? () #3 0x00007ffff56d6ad0 in ?? () #4 0x00007f8671347210 in ?? () #5 0x00007f8671333300 in ?? () #6 0x0000000000000066 in ?? () #7 0x0000000000000000 in ?? () (gdb) l 1361 1362 return pid; 1363 } 1364 1365 SYSCALL_DEFINE0(getuid) 1366 { 1367 /* Only we change this so SMP safe */ 1368 return current_uid(); 1369 } 1370 (gdb) s 1368 return current_uid(); (gdb) get_current () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14 14 return percpu_read_stable(current_task); (gdb) bt #0 get_current () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14 #1 sys_getuid () at kernel/timer.c:1368 #2 0xffffffff810029eb in ?? () #3 0x0000000000000206 in ?? () #4 0x00007ffff56d6ad0 in ?? () #5 0x00007f8671347210 in ?? () #6 0x00007f8671333300 in ?? () #7 0x0000000000000066 in ?? () #8 0x0000000000000000 in ?? () (gdb) l 9 10 DECLARE_PER_CPU(struct task_struct *, current_task); 11 12 static __always_inline struct task_struct *get_current(void) 13 { 14 return percpu_read_stable(current_task); 15 } 16 17 #define current get_current() 18 (gdb) p current_task Cannot access memory at address 0xb540 (gdb) ptype current_task type = struct task_struct { (snip ---Type to continue, or q to quit---q Quit (gdb) s 1368 return current_uid(); (gdb) sys_getuid () at kernel/timer.c:1366 1366 { (gdb) bt #0 sys_getuid () at kernel/timer.c:1366 #1 0xffffffff810029eb in ?? () #2 0x0000000000000206 in ?? () #3 0x00007ffff56d6ad0 in ?? () #4 0x00007f8671347210 in ?? () #5 0x00007f8671333300 in ?? () #6 0x0000000000000066 in ?? () #7 0x0000000000000000 in ?? () (gdb) s 1368 return current_uid(); (gdb) get_current () at kernel/timer.c:1368 1368 return current_uid(); (gdb) bt #0 get_current () at kernel/timer.c:1368 #1 sys_getuid () at kernel/timer.c:1368 #2 0xffffffff810029eb in ?? () #3 0x0000000000000206 in ?? () #4 0x00007ffff56d6ad0 in ?? () #5 0x00007f8671347210 in ?? () #6 0x00007f8671333300 in ?? () #7 0x0000000000000066 in ?? () #8 0x0000000000000000 in ?? () (gdb) l 1363 } 1364 1365 SYSCALL_DEFINE0(getuid) 1366 { 1367 /* Only we change this so SMP safe */ 1368 return current_uid(); 1369 } 1370 1371 SYSCALL_DEFINE0(geteuid) 1372 { (gdb) s sys_getuid () at kernel/timer.c:1369 1369 } (gdb) bt #0 sys_getuid () at kernel/timer.c:1369 #1 0xffffffff810029eb in ?? () #2 0x0000000000000206 in ?? () #3 0x00007ffff56d6ad0 in ?? () #4 0x00007f8671347210 in ?? () #5 0x00007f8671333300 in ?? () #6 0x0000000000000066 in ?? () #7 0x0000000000000000 in ?? () (gdb) l 1364 1365 SYSCALL_DEFINE0(getuid) 1366 { 1367 /* Only we change this so SMP safe */ 1368 return current_uid(); 1369 } 1370 1371 SYSCALL_DEFINE0(geteuid) 1372 { 1373 /* Only we change this so SMP safe */ (gdb) p current_uid No symbol "current_uid" in current context. (gdb) ptype current_uid No symbol "current_uid" in current context. (gdb) s Breakpoint 1, sys_getuid () at kernel/timer.c:1366 1366 { (gdb) detach Ending remote debugging. }}} * include/linux/cred.h {{{#!cc #define current_cred_xxx(xxx) \ ({ \ current->cred->xxx; \ }) #define current_uid() (current_cred_xxx(uid)) #define current_gid() (current_cred_xxx(gid)) (snip) }}} * ptype of current_task->cred {{{ (gdb) ptype current_task->cred type = const struct cred { atomic_t usage; uid_t uid; gid_t gid; uid_t suid; gid_t sgid; uid_t euid; gid_t egid; uid_t fsuid; gid_t fsgid; unsigned int securebits; kernel_cap_t cap_inheritable; kernel_cap_t cap_permitted; kernel_cap_t cap_effective; kernel_cap_t cap_bset; unsigned char jit_keyring; struct key *thread_keyring; struct key *request_key_auth; struct thread_group_cred *tgcred; void *security; struct user_struct *user; struct group_info *group_info; struct rcu_head rcu; } * (gdb) ptype current_task->cred->uid type = unsigned int }}} = 10/19 = == add new system call (i386) == * windell57:i386 s0711489$ vim arch/x86/include/asm/unistd_32.h * windell57:i386 s0711489$ vim arch/x86/kernel/syscall_table_32.S * windell57:i386 s0711489$ vim arch/x86/include/asm/new_hello.h * windell57:i386 s0711489$ vim arch/x86/kernel/new_hello.c = 10/21 = == add new system call (i386) (cont) == * windell57:i386 s0711489$ vim arch/x86/kernel/new_hello.c * windell57:i386 s0711489$ vim arch/x86/kernel/Makefile {{{#!diff Index: arch/x86/kernel/syscall_table_32.S =================================================================== --- arch/x86/kernel/syscall_table_32.S (revision 1352) +++ arch/x86/kernel/syscall_table_32.S (revision 1353) @@ -337,3 +337,4 @@ .long sys_rt_tgsigqueueinfo /* 335 */ .long sys_perf_event_open .long sys_recvmmsg + .long sys_new_hello Index: arch/x86/kernel/Makefile =================================================================== --- arch/x86/kernel/Makefile (revision 1352) +++ arch/x86/kernel/Makefile (revision 1353) @@ -131,3 +131,5 @@ obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o obj-y += vsmp_64.o endif + +obj-y += new_hello.o Index: arch/x86/kernel/new_hello.c =================================================================== --- arch/x86/kernel/new_hello.c (revision 0) +++ arch/x86/kernel/new_hello.c (revision 1353) @@ -0,0 +1,7 @@ +#include +#include + +SYSCALL_DEFINE1(new_hello, int, i) { + printk(KERN_DEBUG "new_hello() syscall with %d", i); + return i; +} Index: arch/x86/include/asm/unistd_32.h =================================================================== --- arch/x86/include/asm/unistd_32.h (revision 1352) +++ arch/x86/include/asm/unistd_32.h (revision 1353) @@ -343,10 +343,11 @@ #define __NR_rt_tgsigqueueinfo 335 #define __NR_perf_event_open 336 #define __NR_recvmmsg 337 +#define __NR_new_hello 338 #ifdef __KERNEL__ -#define NR_syscalls 338 +#define NR_syscalls 339 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR Index: arch/x86/include/asm/new_hello.h =================================================================== --- arch/x86/include/asm/new_hello.h (revision 0) +++ arch/x86/include/asm/new_hello.h (revision 1353) @@ -0,0 +1,7 @@ +#ifndef _ASM_X86_NEW_HELLO_H +#define _ASM_X86_NEW_HELLO_H + +#include +#define new_hello(x) syscall(__NR_new_hello, x) + +#endif /* _ASM_X86_NEW_HELLO_H */ }}} * windell57:i386 s0711489$ make {{{ Kernel: arch/x86/boot/bzImage is ready (#2) }}} * windell57:i386 s0711489$ make modules * s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh * s0711489@ubuntu-lucid:~$ sudo reboot {{{ Linux ubuntu-lucid 2.6.35.14 #2 SMP Fri Oct 21 14:25:51 JST 2011 i686 GNU/Linux Ubuntu 10.04.3 LTS }}} * s0711489@ubuntu-lucid:~$ cat > new_hello.c {{{#!cc #include #include #include int main (void) { printf ("new_helloc(1) -> %d\n", syscall(__NR_new_hello, 1) ); } }}} * s0711489@ubuntu-lucid:~$ gcc -I /lib/modules/2.6.35.14/build/arch/x86/include/ new_hello.c {{{ new_hello.c: In function ‘main’: new_hello.c:8: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long int’ }}} * dmesgにしか出なかったので、KERN_DEBUGを消す * windell57:i386 s0711489$ make {{{ Kernel: arch/x86/boot/bzImage is ready (#3) }}} * windell57:i386 s0711489$ make modules * s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh * s0711489@ubuntu-lucid:~$ sudo reboot * s0711489@ubuntu-lucid:~$ cat > new_hello.c * s0711489@ubuntu-lucid:~$ gcc -I /lib/modules/2.6.35.14/build/arch/x86/include/ new_hello.c * s0711489@ubuntu-lucid:~$ ./a.out {{{ new_helloc(1) -> 1 }}} * s0711489@ubuntu-lucid:~$ dmesg | tail -n 1 {{{ [ 116.986628] new_hello() syscall with 1 }}} * KERN_DEBUGを消したが、結局dmesgにしか出ない * \nの追加 {{{#!diff Index: arch/x86/kernel/new_hello.c =================================================================== --- arch/x86/kernel/new_hello.c (revision 1354) +++ arch/x86/kernel/new_hello.c (revision 1355) @@ -2,6 +2,6 @@ #include SYSCALL_DEFINE1(new_hello, int, i) { - printk(KERN_DEBUG "new_hello() syscall with %d", i); + printk("new_hello() syscall with %d\n", i); return i; } }}} * windell57:i386 s0711489$ make {{{ Kernel: arch/x86/boot/bzImage is ready (#4) }}} * windell57:i386 s0711489$ make modules * s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh * s0711489@ubuntu-lucid:~$ cat > new_hello.c * s0711489@ubuntu-lucid:~$ gcc -I /lib/modules/2.6.35.14/build/arch/x86/include/ new_hello.c * s0711489@ubuntu-lucid:~$ ./a.out {{{ new_helloc(1) -> 1 }}} * s0711489@ubuntu-lucid:~$ ./a.out 1 {{{ new_helloc(2) -> 2 }}} * s0711489@ubuntu-lucid:~$ ./a.out 2 {{{ new_helloc(2) -> 2 }}} * s0711489@ubuntu-lucid:~$ ./a.out 3 {{{ new_helloc(2) -> 2 }}} * s0711489@ubuntu-lucid:~$ ./a.out 1 2 3 4 5 {{{ new_helloc(6) -> 6 }}} * s0711489@ubuntu-lucid:~$ dmesg | tail {{{ [ 62.656820] new_hello() syscall with 1 [ 66.271703] new_hello() syscall with 2 [ 68.411791] new_hello() syscall with 2 [ 70.395934] new_hello() syscall with 2 [ 77.010426] new_hello() syscall with 6 }}} * /var/log/messages /var/log/kern.log /var/log/syslog にも出るようになった {{{ Oct 21 15:29:00 ubuntu-lucid kernel: [ 62.656820] new_hello() syscall with 1 Oct 21 15:29:04 ubuntu-lucid kernel: [ 66.271703] new_hello() syscall with 2 Oct 21 15:29:06 ubuntu-lucid kernel: [ 68.411791] new_hello() syscall with 2 Oct 21 15:29:08 ubuntu-lucid kernel: [ 70.395934] new_hello() syscall with 2 Oct 21 15:29:14 ubuntu-lucid kernel: [ 77.010426] new_hello() syscall with 6 }}} * KERN_DEBUGを戻す {{{#!diff Index: arch/x86/kernel/new_hello.c =================================================================== --- arch/x86/kernel/new_hello.c (revision 1356) +++ arch/x86/kernel/new_hello.c (revision 1357) @@ -2,6 +2,6 @@ #include SYSCALL_DEFINE1(new_hello, int, i) { - printk("new_hello() syscall with %d\n", i); + printk(KERN_DEBUG "new_hello() syscall with %d\n", i); return i; } }}} * windell57:i386 s0711489$ make {{{ Kernel: arch/x86/boot/bzImage is ready (#5) }}} * windell57:i386 s0711489$ make modules * s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh * s0711489@ubuntu-lucid:~$ ./a.out {{{ new_helloc(1) -> 1 }}} * s0711489@ubuntu-lucid:~$ ./a.out 2 {{{ new_helloc(2) -> 2 }}} * s0711489@ubuntu-lucid:~$ ./a.out 2 4 {{{ new_helloc(3) -> 3 }}} * s0711489@ubuntu-lucid:~$ ./a.out 2 3 4 {{{ new_helloc(4) -> 4 }}} * s0711489@ubuntu-lucid:~$ tailf /var/log/syslog {{{ Oct 21 15:39:29 ubuntu-lucid kernel: [ 55.626892] new_hello() syscall with 1 Oct 21 15:40:18 ubuntu-lucid kernel: [ 104.990720] new_hello() syscall with 2 Oct 21 15:40:20 ubuntu-lucid kernel: [ 106.772709] new_hello() syscall with 3 Oct 21 15:40:23 ubuntu-lucid kernel: [ 109.867051] new_hello() syscall with 4 }}} * /var/log/messages には出なくなる === trace sys_new_hello with GDB === * windell57:i386 s0711489$ gdb {{{ (gdb) file vmlinux Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/vmlinux...(no debugging symbols found)...done. (gdb) b sys_new_hello Breakpoint 1 at 0xc101d87c: file arch/x86/kernel/new_hello.c, line 4. (gdb) target remote localhost:8832 Remote debugging using localhost:8832 0xc1007cdf in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/arch/x86/include/asm/irqflags.h:49 49 asm volatile("sti; hlt": : :"memory"); (gdb) c Continuing. Breakpoint 1, sys_new_hello (i=1) at arch/x86/kernel/new_hello.c:4 4 SYSCALL_DEFINE1(new_hello, int, i) { (gdb) n 5 printk(KERN_DEBUG "new_hello() syscall with %d\n", i); (gdb) l 1 #include 2 #include 3 4 SYSCALL_DEFINE1(new_hello, int, i) { 5 printk(KERN_DEBUG "new_hello() syscall with %d\n", i); 6 return i; 7 } (gdb) s printk (fmt=0xc1449502 "<7>new_hello() syscall with %d\n") at kernel/printk.c:614 614 va_start(args, fmt); (gdb) l 609 r = vkdb_printf(fmt, args); 610 va_end(args); 611 return r; 612 } 613 #endif 614 va_start(args, fmt); 615 r = vprintk(fmt, args); 616 va_end(args); 617 618 return r; (gdb) n 615 r = vprintk(fmt, args); (gdb) 614 va_start(args, fmt); (gdb) 615 r = vprintk(fmt, args); (gdb) 619 } (gdb) sys_new_hello (i=1) at arch/x86/kernel/new_hello.c:7 7 } (gdb) l 2 #include 3 4 SYSCALL_DEFINE1(new_hello, int, i) { 5 printk(KERN_DEBUG "new_hello() syscall with %d\n", i); 6 return i; 7 } (gdb) s }}} * s0711489@ubuntu-lucid:~$ ./a.out {{{ new_helloc(1) -> 1 }}} === add sys_new_hello entry === * windell57:i386 s0711489$ vim include/linux/syscalls.h {{{#!diff Index: include/linux/syscalls.h =================================================================== --- include/linux/syscalls.h (revision 1358) +++ include/linux/syscalls.h (revision 1359) @@ -826,4 +826,6 @@ unsigned long fd, unsigned long pgoff); asmlinkage long sys_old_mmap(struct mmap_arg_struct __user *arg); +asmlinkage long sys_new_hello(int i); + #endif }}} * windell57:i386 s0711489$ make {{{ Kernel: arch/x86/boot/bzImage is ready (#6) }}} * windell57:i386 s0711489$ make modules * s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh * s0711489@ubuntu-lucid:~$ ./a.out {{{ new_helloc(1) -> 1 }}} * s0711489@ubuntu-lucid:~$ ./a.out 2 {{{ new_helloc(2) -> 2 }}} * s0711489@ubuntu-lucid:~$ ./a.out 2 3 {{{ new_helloc(3) -> 3 }}} * s0711489@ubuntu-lucid:~$ tailf /var/log/kern.log {{{ Oct 21 16:16:20 ubuntu-lucid kernel: [ 59.045533] new_hello() syscall with 1 Oct 21 16:16:22 ubuntu-lucid kernel: [ 61.043321] new_hello() syscall with 2 Oct 21 16:16:24 ubuntu-lucid kernel: [ 63.470397] new_hello() syscall with 3 }}} == add new system call (x86_64) == * viola04:linux-2.6.35.14 s0711489$ svn cp i386/arch/x86/include/asm/new_hello.h x86_64/arch/x86/include/asm/new_hello.h * viola04:linux-2.6.35.14 s0711489$ svn cp i386/arch/x86/kernel/new_hello.c x86_64/arch/x86/kernel/ * viola04:linux-2.6.35.14 s0711489$ svn merge i386/include/linux/syscalls.h x86_64/include/linux/syscalls.h -r 1358:1359 = 10/26 = == add new system call (x86_64) (cont) == * viola06:x86_64 s0711489$ svn revert include/linux/syscalls.h arch/x86/kernel/new_hello.c arch/x86/include/asm/new_hello.h * viola06:x86_64 s0711489$ rm arch/x86/kernel/new_hello.c arch/x86/include/asm/new_hello.h * viola06:linux-2.6.35.14 s0711489$ svn merge i386/arch/ x86_64/arch/ -r1352:1359 * viola06:linux-2.6.35.14 s0711489$ svn merge i386/include/ x86_64/include/ -r1358:1359 * viola04:x86_64 s0711489$ vim arch/x86/include/asm/unistd_64.h {{{ Index: include/linux/syscalls.h =================================================================== --- include/linux/syscalls.h (revision 1367) +++ include/linux/syscalls.h (revision 1368) @@ -826,4 +826,6 @@ unsigned long fd, unsigned long pgoff); asmlinkage long sys_old_mmap(struct mmap_arg_struct __user *arg); +asmlinkage long sys_new_hello(int i); + #endif Index: include =================================================================== --- include (revision 1367) +++ include (revision 1368) Property changes on: include ___________________________________________________________________ Added: svn:mergeinfo Merged /trunk/coursework/KernelHack/linux-2.6.35.14/i386/include:r1359 Index: arch/x86/kernel/syscall_table_32.S =================================================================== --- arch/x86/kernel/syscall_table_32.S (revision 1367) +++ arch/x86/kernel/syscall_table_32.S (revision 1368) @@ -337,3 +337,4 @@ .long sys_rt_tgsigqueueinfo /* 335 */ .long sys_perf_event_open .long sys_recvmmsg + .long sys_new_hello Index: arch/x86/kernel/Makefile =================================================================== --- arch/x86/kernel/Makefile (revision 1367) +++ arch/x86/kernel/Makefile (revision 1368) @@ -131,3 +131,5 @@ obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o obj-y += vsmp_64.o endif + +obj-y += new_hello.o Index: arch/x86/kernel/new_hello.c =================================================================== --- arch/x86/kernel/new_hello.c (revision 0) +++ arch/x86/kernel/new_hello.c (revision 1368) @@ -0,0 +1,7 @@ +#include +#include + +SYSCALL_DEFINE1(new_hello, int, i) { + printk(KERN_DEBUG "new_hello() syscall with %d\n", i); + return i; +} Index: arch/x86/include/asm/unistd_32.h =================================================================== --- arch/x86/include/asm/unistd_32.h (revision 1367) +++ arch/x86/include/asm/unistd_32.h (revision 1368) @@ -343,10 +343,11 @@ #define __NR_rt_tgsigqueueinfo 335 #define __NR_perf_event_open 336 #define __NR_recvmmsg 337 +#define __NR_new_hello 338 #ifdef __KERNEL__ -#define NR_syscalls 338 +#define NR_syscalls 339 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR Index: arch/x86/include/asm/new_hello.h =================================================================== --- arch/x86/include/asm/new_hello.h (revision 0) +++ arch/x86/include/asm/new_hello.h (revision 1368) @@ -0,0 +1,7 @@ +#ifndef _ASM_X86_NEW_HELLO_H +#define _ASM_X86_NEW_HELLO_H + +#include +#define new_hello(x) syscall(__NR_new_hello, x) + +#endif /* _ASM_X86_NEW_HELLO_H */ Index: arch/x86/include/asm/unistd_64.h =================================================================== --- arch/x86/include/asm/unistd_64.h (revision 1367) +++ arch/x86/include/asm/unistd_64.h (revision 1368) @@ -663,6 +663,8 @@ __SYSCALL(__NR_perf_event_open, sys_perf_event_open) #define __NR_recvmmsg 299 __SYSCALL(__NR_recvmmsg, sys_recvmmsg) +#define __NR_new_hello 300 +__SYSCALL(__NR_new_hello, sys_new_hello) #ifndef __NO_STUBS #define __ARCH_WANT_OLD_READDIR Index: arch =================================================================== --- arch (revision 1367) +++ arch (revision 1368) Property changes on: arch ___________________________________________________________________ Added: svn:mergeinfo Merged /trunk/coursework/KernelHack/linux-2.6.35.14/i386/arch:r1353-1359 }}} * viola06:x86_64 s0711489$ make -j 16 {{{ Kernel: arch/x86/boot/bzImage is ready (#2) }}} * viola06:x86_64 s0711489$ make modules * s0711489@ubuntu-lucid64:~$ sudo /mnt/hgfs/tools/install.sh * s0711489@ubuntu-lucid64:~/KernelHack/03$ uname -a {{{ Linux ubuntu-lucid64 2.6.32-33-generic #72-Ubuntu SMP Fri Jul 29 21:07:13 UTC 2011 x86_64 GNU/Linux }}} * s0711489@ubuntu-lucid64:~/KernelHack/03$ gcc -I /lib/modules/2.6.35.14/build/arch/x86/include/ new_hello.c {{{ new_hello.c: In function ‘main’: new_hello.c:9: warning: format ‘%d’ expects type ‘int’, but argument 3 has type ‘long int’ }}} * s0711489@ubuntu-lucid64:~/KernelHack/03$ ./a.out {{{ new_hello(1) -> -1 }}} * reboot 前はsyscallが存在しない * s0711489@ubuntu-lucid64:~$ sudo reboot * s0711489@ubuntu-lucid64:~$ uname -a {{{ Linux ubuntu-lucid64 2.6.35.14 #2 SMP Wed Oct 26 13:06:41 JST 2011 x86_64 GNU/Linux }}} * s0711489@ubuntu-lucid64:~/KernelHack/03$ ./a.out {{{ new_hello(1) -> 1 }}} * s0711489@ubuntu-lucid64:~/KernelHack/03$ ./a.out 2 {{{ new_hello(2) -> 2 }}} * s0711489@ubuntu-lucid64:~/KernelHack/03$ ./a.out 2 3 {{{ new_hello(3) -> 3 }}} * s0711489@ubuntu-lucid64:~/KernelHack/03$ ./a.out 2 3 4 {{{ new_hello(4) -> 4 }}} * s0711489@ubuntu-lucid64:~/KernelHack/03$ tail /var/log/kern.log {{{ Oct 26 13:12:40 ubuntu-lucid64 kernel: [ 40.542158] new_hello() syscall with 1 Oct 26 13:12:42 ubuntu-lucid64 kernel: [ 42.668465] new_hello() syscall with 2 Oct 26 13:12:43 ubuntu-lucid64 kernel: [ 43.908292] new_hello() syscall with 3 Oct 26 13:12:45 ubuntu-lucid64 kernel: [ 45.645548] new_hello() syscall with 4 }}} = 10/28 = * [http://www.bugbearr.jp/?C%E8%A8%80%E8%AA%9E%2F%E6%97%A5%E6%99%82 C言語/日時 - BugbearR's Wiki] * http://linuxjm.sourceforge.jp/html/LDP_man-pages/man2/clock_gettime.2.html * [http://d.hatena.ne.jp/pyopyopyo/20060711/p1 linuxで時刻を取得する方法 - ぴょぴょぴょ? - Linuxとかプログラミングの覚え書き -] * [http://linux.die.net/man/2/intro intro(2): Introduction to system calls - Linux man page] > System calls are not required to return only positive or negative error codes. You need to read the source to be sure how it will return errors. Usually, it is the negative of a standard error code, e.g., -EPERM. The _syscall() macros will return the result r of the system call when r is non-negative, but will return -1 and set the variable errno to -r when r is negative.