[系统技巧] 如何理解Linux内核IS_ERR、ERR_PTR、PTR_ERR
作者:CC下载站 日期:2023-10-11 23:53:50 浏览:29 分类:玩电脑
一、如何理解一些特殊的符号
1)inline:内联函数。内联函数的代码会直接嵌入到调用它的位置,调用几次就复制几次。
2)__must_check:调用函数时一定要处理函数的返回值,否则编译器会给出警告。
3)unlikely:告诉编译器括号内的值发生的概率很低,编译器就根据这个提示信息去做一些分支预测的编译优化。
4)(unsigned long)-MAX_ERRNO:用补码的方式表示-4095,32位系统为0xfffff001。
二、内核空间的指针类型
1)有效指针;
2)NULL,空指针;
3)错误指针,或者说无效指针。
三、如何理解内核空间最大的错误码
1. 对于32位的系统来说,内核空间占用 3~4G(0xc0000000~0xffffffff)的虚拟地址。其中Linux采用了分页机制来管理内存,而CPU访问的是线性地址需要通过页表来转化成物理地址。所以,内核就约定了留出最后一个page(假设4k一个page)0xfffff000~0xffffffff,专门用来记录内核空间的错误指针。
2. 在 <linux/err.h> 中定义了 #define MAX_ERRNO 4095 最大错误码为 4095。至于这里为什么是 4095,而不是其它值?
我们知道负数在计算机中以二进制补码形式存储。因此,(unsigned long)-MAX_ERRNO 的值为0xfffff001,也就是大于等于 0xfffff001 的指针为非法指针。
注意 (unsigned long)-MAX_ERRNO 并不是 (unsigned long)减去MAX_ERRNO,而是对 -MAX_ERRNO 进行强制类型转化,其应该等价于 (unsigned long)(-MAX_ERRNO),-4095转换为无符号long型是0xfffff001,即:
#define IS_ERR_VALUE(x) unlikely((x) >= 0xfffff001)
四、解读内核相关内联函数的含义
1)IS_ERR() 调用了 IS_ERR_VALUE(),并将指针强转为 unsigned long 类型的错误码:IS_ERR() 判断指针是否非法,如果指针 < 0xfffff001 是有效的;如果指针 >= 0xfffff001 是无效的。即在 (0xfffff001,0xffffffff) 之间的就是错误指针。因此,可以用IS_ERR()来判断内核的指针是否有效。所以在内核中能经常看到返回负数的错误码如:-ENODEV。 参考内核对该函数的使用:
static struct sp_node *sp_alloc(unsigned long start, unsigned long end, struct mempolicy *pol) { struct sp_node *n; struct mempolicy *newpol; n = kmem_cache_alloc(sn_cache, GFP_KERNEL); if (!n) return NULL; newpol = mpol_dup(pol); if (IS_ERR(newpol)) { kmem_cache_free(sn_cache, n); return NULL; } newpol->flags |= MPOL_F_SHARED; sp_node_init(n, start, end, newpol); return n; }
2)ERR_PTR() 将一个错误码强转为一个错误指针,并作为函数的返回值使用。 参考内核对该函数的使用:
struct net_device *tc515_probe(int unit) { struct net_device *dev = corkscrew_scan(unit); static int printed; if (!dev) return ERR_PTR(-ENODEV); if (corkscrew_debug > 0 && !printed) { printed = 1; pr_debug("%s", version); } return dev; }
3)PTR_ERR() 将一个错误指针强转为一个错误码,并作为函数的返回值使用。 参考内核对该函数的使用:
static int vma_replace_policy(struct vm_area_struct *vma, struct mempolicy *pol) { int err; struct mempolicy *old; struct mempolicy *new; pr_debug("vma %lx-%lx/%lx vm_ops %p vm_file %p set_policy %p\n", vma->vm_start, vma->vm_end, vma->vm_pgoff, vma->vm_ops, vma->vm_file, vma->vm_ops ? vma->vm_ops->set_policy : NULL); new = mpol_dup(pol); if (IS_ERR(new)) return PTR_ERR(new); if (vma->vm_ops && vma->vm_ops->set_policy) { err = vma->vm_ops->set_policy(vma, new); if (err) goto err_out; } old = vma->vm_policy; vma->vm_policy = new; /* protected by mmap_sem */ mpol_put(old); return 0; err_out: mpol_put(new); return err; }
五、附上内核源码(include/linux/err.h)
#include <linux/compiler.h> #include <asm/errno.h> /* * Kernel pointers have redundant information, so we can use a * scheme where we can return either an error code or a dentry * pointer with the same return value. * * This should be a per-architecture thing, to allow different * error and pointer decisions. */ #define MAX_ERRNO 4095 #define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO) static inline void * __must_check ERR_PTR(long error) { return (void *) error; } static inline long __must_check PTR_ERR(const void *ptr) { return (long) ptr; } static inline long __must_check IS_ERR(const void *ptr) { return IS_ERR_VALUE((unsigned long)ptr); } static inline long __must_check IS_ERR_OR_NULL(const void *ptr) { return !ptr || IS_ERR_VALUE((unsigned long)ptr); }
猜你还喜欢
- 03-06 [工具测试] 使用 go-ycsb 对 etcd 进行基准 (benchmark) 性能测试
- 10-12 [软件教程] MobaXterm 安装使用教程【图解】
- 10-12 [软件技巧] 避开SS524V100 GDB的坑
- 10-12 [系统技巧] Linux CPU网卡软中断性能调优
- 10-11 [系统技巧] Linux内核的 EXPORT_SYMBOL 和 EXPORT_SYMBOL_GPL 的作用
- 10-11 [玩软件] 海思 fw_printenv 和 fw_setenv 工具详解
- 10-11 [系统技巧] Linux top 命令解析及使用
- 10-11 [系统教程] Linux WEXITSTATUS 宏讲解
- 10-11 [Python] python 创建 Telnet 客户端
- 08-16 [嗅探工具] HTTP Debugger Pro 9.11 汉化版
- 08-13 [WordPress / 扩展插件] WordPress缓存插件 WP Rocket v3.11.3 去广告破解版
- 03-15 [福利分享] 免费ftp服务器地址汇总
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[小说] 【飞卢小说】2100+本合集
[PPT模板] 160套收费高质量毕业答辩PPT模板
[小说] 付费小说300+
[文章合集] 知乎盐选付费文章合集,2888部
[书籍] 《高分图书50部》好书共读 休闲 成长 生活一个都不能少[epub]
[游戏娱乐] 《我的梦想卧室》v20240413中文版
[资料] 知识星球 付费课程(精选130篇)[PDF]
[有声读物] 冯唐讲《资治通鉴》(完结)【MP3】
[电影] 2022年国产奇幻片《聊斋新传之画皮人》HD国语中字
[书籍] 国学书籍70本(绝版珍藏)【TXT】
[资料] [大学期末救急课] 猴博士+高斯课堂+斐多课堂,全集视频合集
[云资源] 价值2万元的老男孩Python教程
[书库] 史上最全摄影书推荐(附700本PDF版打包下载)
[云资源] 花了一千多元买的私人健身教程
[下载工具] Internet Download Manager 6.42.7 (IDM)
[影视] 灌篮高手 WEB-DL版下载/Slam Dunk/スラムダンク/灌篮高手:THE FIRST/灌篮高手电影版 2022 The First Slam Dunk 61.35G
[即时通讯] 腾讯QQ PC版9.7.22.29315去广告绿色纯净版
[开发环境] PhpStorm2023中文激活版v2023.3.3 正式版
[资料] 3000 套电影电视剧 LOGO 宣传片常用音效合集包
[安卓软件] 酷我音乐APP_v10.7.6.4 去广告破解豪华VIP版
[云资源] 价值2万元的老男孩Python教程
[影视] 灌篮高手 WEB-DL版下载/Slam Dunk/スラムダンク/灌篮高手:THE FIRST/灌篮高手电影版 2022 The First Slam Dunk 61.35G
[云资源] 花了一千多元买的私人健身教程
[书库] 史上最全摄影书推荐(附700本PDF版打包下载)
[动画] 北斗神拳(1984) [两季合集] [MKV]
[资料] 抗战阵亡将士资料+续编
[电视剧] 三体 (2024) 全8集 网飞版本 中文字幕 合集
[影视] 三大队 WEB-DL版下载/Endless Journey/请转告局长,三大队任务完成了 2023 三大队 6.7G
[纪录片] 河西走廊【10集 国语 中文字幕 1080P 10.8G MP4】
[安卓软件] OfficeSuite中文版APP v14.2.50872.0破解版
- 最新评论
-
好东西阿zfy123123 评论于:04-18 谢谢楼主xiaoqi 评论于:04-12 勿在线解压,勿手机解压,请在电脑上用最新款压缩软件解压!推荐360压缩或者好压CC下载站 评论于:04-10 无法解压啊,客服能不能给个解压教程ravengrey 评论于:04-10 谢谢支持!!CC下载站 评论于:03-26 很棒的资源,感谢分享云体风身 评论于:03-26 感谢分享,好东西云体风身 评论于:03-26 谢谢支持!CC下载站 评论于:03-14 央视精品,感谢付出提供。qwer9009 评论于:03-14 谢谢支持!!!CC下载站 评论于:03-13
- 热门tag