为何bpftrace将char指针视为整数?如何修复相关报错?
bpftrace访问d_name.name类型不匹配及语法错误问题解决
问题场景
执行了如下bpftrace命令:
bpftrace -e 'kprobe:f2fs_file_write_iter { printf("process:%s file:%s inode:%ld offset:%ld count:%ld\n", comm, (((struct kiocb *)arg0)->ki_filp->f_path.dentry->d_name.name), ((struct kiocb *)arg0)->ki_filp->f_inode->i_ino, ((struct kiocb *)arg0)->ki_pos, ((struct iov_iter *)arg1)->count ); }'
触发报错:
stdin:1:31-284: ERROR: printf: %s specifier expects a value of type string (integer supplied)
根据Linux内核源码,((struct kiocb *)arg0)->ki_filp->f_path.dentry->d_name.name为char指针类型,但bpftrace将其识别为整数。尝试通过(char *)强制转换时,又出现语法错误:
root@localhost:/usr/share/bcc/tools# bpftrace -e 'kprobe:f2fs_file_write_iter { printf("process:%s file:%s inode:%ld offset:%ld count:%ld\n", comm, (char *)(((struct kiocb *)arg0)->ki_filp->f_path.dentry->d_name.name), ((struct kiocb *)arg0)->ki_filp->f_inode->i_ino, ((struct kiocb *)arg0)->ki_pos, ((struct iov_iter *)arg1)->count ); }'
报错信息:
stdin:1:107-109: ERROR: syntax error, unexpected ) kprobe:f2fs_file_write_iter { printf("process:%s file:%s inode:%ld offset:%ld count:%ld\n", comm, (char *)(((struct kiocb *)arg0)->ki_filp->f_path.dentry->d_name.name), ((struct kiocb *)arg0)->ki_filp->f_inode->i_ino, ((struct kiocb *)arg0)->ki_pos, ((struct iov_iter *)arg1)->count ); }
问题原因
- 类型推断限制:bpftrace的类型识别机制无法自动将内核空间的char指针映射为字符串类型,会把指针的地址值当作整数处理,导致
printf的%s格式符参数类型不匹配。 - 语法规则限制:bpftrace不支持在
printf的参数列表中直接使用C风格的强制类型转换,因此(char *)的写法会触发语法解析错误。
修复方案
使用bpftrace内置的str()函数将内核char指针转换为字符串类型,替换强制类型转换操作。修改后的命令如下:
bpftrace -e 'kprobe:f2fs_file_write_iter { printf("process:%s file:%s inode:%ld offset:%ld count:%ld\n", comm, str(((struct kiocb *)arg0)->ki_filp->f_path.dentry->d_name.name), ((struct kiocb *)arg0)->ki_filp->f_inode->i_ino, ((struct kiocb *)arg0)->ki_pos, ((struct iov_iter *)arg1)->count ); }'
关键说明
str()是bpftrace专为内核字符串读取设计的函数,能自动将内核空间的char指针转换为bpftrace可识别的字符串类型,完美适配%s格式符。- 该函数会内置处理字符串读取的边界检查,避免越界访问问题,比手动强制转换更安全可靠。
内容的提问来源于stack exchange,提问作者Jun
相关产品推荐
相关产品推荐

