[系统技巧] 如何理解Linux内核IS_ERR、ERR_PTR、PTR_ERR
作者:精品下载站 日期:2023-10-11 23:53:50 浏览:73 分类:玩电脑
一、如何理解一些特殊的符号
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-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[短剧合集] 2025年06月2日 精选+付费短剧推荐39部
[软件合集] 25年6月2日 精选软件18个
[软件合集] 25年6月1日 精选软件15个
[短剧合集] 2025年06月1日 精选+付费短剧推荐59部
[短剧] 2025年05月31日 精选+付费短剧推荐58部
[软件合集] 25年5月31日 精选软件66个
[电影] 黄沙漫天(2025) 4K.EDRMAX.杜比全景声 / 4K杜比视界/杜比全景声
[风口福利] 短视频红利新风口!炬焰创作者平台重磅激励来袭
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[美图] 2W美女个美女小姐姐,饱眼福
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag