系统调用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
相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
目录
相关文章
|
2月前
|
存储 Unix Linux
Linux文件描述符和打开文件之间的关系
文件描述符和打开的文件之间似乎呈现出一一对应的关系。然而,实际并非如此。多个文件描述符指向同一打开文件,这既有可能,也属必要。这些文件描述符可在相同或不同的进程中打开。要理解具体情况如何,需要查看由内核维护的 3 个数据结构。进程级的文件描述符表。系统级的打开文件表。文件系统的 i-node 表。上述讨论揭示出如下要点。两个不同的文件描述符,若指向同一打开文件句柄,将共享同一文件偏移量。
25 0
Linux文件描述符和打开文件之间的关系
|
2月前
|
存储 Linux
Linux文件编程(lseek函数和stat函数)
Linux文件编程(lseek函数和stat函数)
53 0
Linux文件编程(lseek函数和stat函数)
|
存储 API Windows
驱动开发:内核中进程与句柄互转
在内核开发中,经常需要进行进程和句柄之间的互相转换。进程通常由一个唯一的进程标识符(PID)来标识,而句柄是指对内核对象的引用。在Windows内核中,`EProcess`结构表示一个进程,而HANDLE是一个句柄。为了实现进程与句柄之间的转换,我们需要使用一些内核函数。对于进程PID和句柄的互相转换,可以使用函数如`OpenProcess`和`GetProcessId`。OpenProcess函数接受一个PID作为参数,并返回一个句柄。GetProcessId函数接受一个句柄作为参数,并返回该进程的PID。
331 0
|
Linux
Linux系统调用六、stat函数与 struct stat 文件信息结构体深度刨析(一)
Linux系统调用六、stat函数与 struct stat 文件信息结构体深度刨析
179 0
Linux系统调用六、stat函数与 struct stat 文件信息结构体深度刨析(一)
|
Linux
Linux系统调用六、stat函数与 struct stat 文件信息结构体深度刨析(三)
Linux系统调用六、stat函数与 struct stat 文件信息结构体深度刨析
311 0
Linux系统调用六、stat函数与 struct stat 文件信息结构体深度刨析(三)
|
NoSQL Linux 开发工具
Linux系统调用六、stat函数与 struct stat 文件信息结构体深度刨析(二)
Linux系统调用六、stat函数与 struct stat 文件信息结构体深度刨析
177 0
Linux系统调用六、stat函数与 struct stat 文件信息结构体深度刨析(二)
|
Linux C语言
Linux系统调用一、系统调用与C库函数的关系 —— 从进程虚拟地址空间和文件描述符的角度分析
Linux系统调用一、系统调用与C库函数的关系 —— 从进程虚拟地址空间和文件描述符的角度分析
181 0
Linux系统调用一、系统调用与C库函数的关系 —— 从进程虚拟地址空间和文件描述符的角度分析
|
缓存 Linux API
系统编程之文件IO(七)——0,1,2三个文件描述符与库函数和系统调用的区别
系统编程之文件IO(七)——0,1,2三个文件描述符与库函数和系统调用的区别
系统编程之文件IO(七)——0,1,2三个文件描述符与库函数和系统调用的区别
驱动开发:内核遍历进程VAD结构体
在上一篇文章`《驱动开发:内核中实现Dump进程转储》`中我们实现了ARK工具的转存功能,本篇文章继续以内存为出发点介绍`VAD`结构,该结构的全程是`Virtual Address Descriptor`即`虚拟地址描述符`,VAD是一个`AVL`自`平衡二叉树`,树的每一个节点代表一段虚拟地址空间。程序中的代码段,数据段,堆段都会各种占用一个或多个`VAD`节点,由一个`MMVAD`结构完整描述。
441 0
驱动开发:内核遍历进程VAD结构体
|
缓存 Linux C语言
库函数与系统调用之间的区别--扩展知识点1
库函数与系统调用之间的区别--扩展知识点1
148 0