想要知道该down_read所处的位置
crash> bt 1620
PID: 1620 TASK: ffff88812edb4a00 CPU: 6 COMMAND: "mount_clear_soc"
#0 [ffffc900005e3c88] __schedule at ffffffff82248906
#1 [ffffc900005e3d18] schedule at ffffffff82249262
#2 [ffffc900005e3d28] rwsem_down_read_slowpath at ffffffff8224e094
#3 [ffffc900005e3dd0] down_read at ffffffff8224e676 #想要知道该down_read所处的位置
#4 [ffffc900005e3de0] __get_super at ffffffff8145f7a3 #执行dis -l ffffffff8145f7a3
#5 [ffffc900005e3e18] get_super at ffffffff8145f814
#6 [ffffc900005e3e20] __invalidate_device at ffffffff814ca4ec
#7 [ffffc900005e3e40] nbd_ioctl at ffffffff81cd1725
#8 [ffffc900005e3ea8] blkdev_ioctl at ffffffff81a65cbf
#9 [ffffc900005e3ef0] block_ioctl at ffffffff814ca42a
#10 [ffffc900005e3ef8] ksys_ioctl at ffffffff8147dcb0
#11 [ffffc900005e3f30] __x64_sys_ioctl at ffffffff8147dd6e
#12 [ffffc900005e3f38] do_syscall_64 at ffffffff81003f1b
#13 [ffffc900005e3f50] entry_SYSCALL_64_after_hwframe at ffffffff82400078
RIP: 00007f568032c577 RSP: 00007ffc7b1d6d58 RFLAGS: 00000202
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f568032c577
RDX: 0000000000000000 RSI: 000000000000ab04 RDI: 0000000000000003
RBP: 0000000000001388 R8: 00007f568080c440 R9: 0000000000000000
R10: 0000000000000003 R11: 0000000000000202 R12: 0000000000000003
R13: 00007ffc7b1d747b R14: 0000000000000653 R15: 0000000000000000
ORIG_RAX: 0000000000000010 CS: 0033 SS: 002b
crash> dis -l ffffffff8145f7a3
/home/sunke/git/linux/fs/super.c: 759
0xffffffff8145f7a3 : addq $0x1,0x4fc9315(%rip) # 0xffffffff86428ac0
根据结构体地址,推断结构体成员的地址
已知super_block的地址为ffff88812ef99800
求成员struct rw_semaphore s_umount的地址,并分析其内容
crash> whatis -o super_block
struct super_block {
[0] struct list_head s_list;
[16] dev_t s_dev;
[20] unsigned char s_blocksize_bits;
[24] unsigned long s_blocksize;
[32] loff_t s_maxbytes;
[40] struct file_system_type *s_type;
[48] const struct super_operations *s_op;
[56] const struct dquot_operations *dq_op;
[64] const struct quotactl_ops *s_qcop;
[72] const struct export_operations *s_export_op;
[80] unsigned long s_flags;
[88] unsigned long s_iflags;
[96] unsigned long s_magic;
[104] struct dentry *s_root;
[112] struct rw_semaphore s_umount; #相对偏移为112,也就是0x70
[152] int s_count;
[156] atomic_t s_active;
[160] const struct xattr_handler **s_xattr;
...
推测出s_umount的地址为ffff88812ef99870
然后可以看其内容了
crash> rw_semaphore ffff88812ef99870
struct rw_semaphore {
count = {
counter = 3
},
owner = {
counter = -131386559987712
},
osq = {
tail = {
counter = 0
}
},
wait_lock = {
raw_lock = {
{
val = {
counter = 0
},
{
locked = 0 '\000',
pending = 0 '\000'
},
{
locked_pending = 0,
tail = 0
}
}
}
},
wait_list = {
next = 0xffffc9000650bd60,
prev = 0xffffc9000650bd60
}
}
进一步获取当前拥有该信号量的进程的pid,需要对owner用结构体进一步task_struct进一步解析,由于在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。所以需要进行转化。需要将long型的值强制转换成unsigned long,为18446612687149563904,再转成十六进制为ffff88812ec38000
crash> task_struct ffff88812ec38000
struct task_struct {
thread_info = {
flags = 16384,
status = 0
},
state = 2,
stack = 0xffffc90007af0000,
......
pid = 21769, #当前占有信号量的进程
tgid = 21769,
stack_canary = 14636143678320973568,
real_parent = 0xffff88812ece0000,
parent = 0xffff88812ece0000,
children = {
next = 0xffff88812ec388a8,
prev = 0xffff88812ec388a8
},
......
作者:jfhgk3445