系统调用lseek和内核file结构体之间的关系-阿里云开发者社区

开发者社区> 数据库> 正文

系统调用lseek和内核file结构体之间的关系

简介: 大家都知道lseek就是移动文件的读写位置, 也就是对应内核中file结构体中的某一个变量, 今天就是特别想看一下具体之间的关系. 软件就在于实践 首先需要有一个很方便调用lseek的环境, 这样才不会影响我们调试的兴趣, 希望能达到像python, matlab这样每个函数可以手动跑, 而不像c语言一样要编写, 然后编译, 然后执行, 然后再修改, 编译. gdb可以 1. 先准备文件

大家都知道lseek就是移动文件的读写位置, 也就是对应内核中file结构体中的某一个变量, 今天就是特别想看一下具体之间的关系.
软件就在于实践

首先需要有一个很方便调用lseek的环境, 这样才不会影响我们调试的兴趣, 希望能达到像python, matlab这样每个函数可以手动跑, 而不像c语言一样要编写, 然后编译, 然后执行, 然后再修改, 编译. gdb可以

  1. 先准备文件1.c, 前面的头文件很重要, 不能漏
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int main()
{
return 0;
}
gcc 1.c -ggdb3

-ggdb3是为了能方便的使用宏

gdb ./a.out
b main
r

接下来会使用call open来打开文件, 但是如何找到我们将要打开的文件在内核中的file结构体的地址呢? kgtp
找到a.out进程号是1138

找到内核do_sys_open源代码

1012 long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
1013 {
1014 struct open_flags op;
1015 int lookup = build_open_flags(flags, mode, &op);
1016 struct filename *tmp = getname(filename);
1017 int fd = PTR_ERR(tmp);
(gdb) 
1018
1019 if (!IS_ERR(tmp)) {
1020 fd = get_unused_fd_flags(flags);
1021 if (fd >= 0) {
1022 struct file *f = do_filp_open(dfd, tmp, &op, lookup);
1023 if (IS_ERR(f)) {

所以要在1023设置tracepoint找到f的值, 并且使用pid 1138来过滤, 总结就是要得到进程1138调用do_sys_open的时候的f的值
kgtp命令

tmp=`mktemp`; echo 'set pagination off
set confirm off
set circular-trace-buffer on
target remote /sys/kernel/debug/gtp
d
trace open.c:1023
actions
collect f
end
tstart' > $tmp; echo $tmp; cat $tmp; sudo gdb /usr/lib/debug/lib/modules/3.10.0-327.el7.x86_64/vmlinux -x $tmp
`f' has been optimized out, cannot use

但是发现f被优化, 只能找汇编地址来定位f的值

0xffffffff811dd7de <+238>: callq 0xffffffff811efdf0 <do_filp_open>
0xffffffff811dd7e3 <+243>: cmp $0xfffffffffffff000,%rax

所以tracepoint到0xffffffff811dd7e3
kgtp的命令

tmp=`mktemp`; echo 'set pagination off
set confirm off
set circular-trace-buffer on
target remote /sys/kernel/debug/gtp
d
trace *0xffffffff811dd7e3 if ((struct task_struct *)$current_task)->pid == 1138
actions
collect $rax
end
tstart' > $tmp; echo $tmp; cat $tmp; sudo gdb /usr/lib/debug/lib/modules/3.10.0-327.el7.x86_64/vmlinux -x $tmp

Tracepoint 1 at 0xffffffff811dd7e3: file fs/open.c, line 1023

回到gdb中手动调用call open

(gdb) call open("/root/1.c", O_WRONLY )
$5 = 7

回到kgtp中查看f的值

(gdb) p/x $rax
$3 = 0xffff88003ad2ee00
(gdb) tfind -1
(gdb) p ((struct file*)$3)->f_pos
$7 = 0

到gdb中call lseek

(gdb) call lseek(7, 1, 0)
$6 = 1

查看file结构体

p ((struct file*)$3)->f_pos
$9 = 1

到gdb中call lseek

(gdb) call lseek(7, 234, 0)
$7 = 234

查看file结构体

(gdb) p ((struct file*)$3)->f_pos
$10 = 234

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
数据库
使用钉钉扫一扫加入圈子
+ 订阅

分享数据库前沿,解构实战干货,推动数据库技术变革

其他文章