[系统技巧] 如何理解Linux内核IS_ERR、ERR_PTR、PTR_ERR
作者:CC下载站 日期:2023-10-11 23:53:50 浏览:35 分类:玩电脑
一、如何理解一些特殊的符号
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服务器地址汇总
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[书籍] 《炁体源流(上下册)》 道家养生经典辑录 米晶子[pdf]
[即时翻译] 实时打字翻译工具-Typing-translationV3.0
[转换工具] TMSpeech 1.0免费实时语音转字幕软件
[Android] 电工计算器 v10.0.2.1-h
[美食] 曾经的黑龙江第一城,藏着中国烧烤王者
[媒体编辑] pyVideoTrans视频翻译和配音 v1.42
[趣味工具] 【桌面动态小装扮】蝴蝶1.0、蟑螂1.2、苍蝇1.3
[辅助工具] 《小说角色更名器》+《小说广告清理器》V2.0.1
[Android] 人体穴位图解 v3.1.3(可离线)支持Android + ios
[辅助工具] 微信朋友圈导出工具 WechatMoments v0.0.1便携版
[资料] [大学期末救急课] 猴博士+高斯课堂+斐多课堂,全集视频合集
[云资源] 价值2万元的老男孩Python教程
[书库] 史上最全摄影书推荐(附700本PDF版打包下载)
[云资源] 花了一千多元买的私人健身教程
[下载工具] Internet Download Manager 6.42.7 (IDM)
[影视] 灌篮高手 WEB-DL版下载/Slam Dunk/スラムダンク/灌篮高手:THE FIRST/灌篮高手电影版 2022 The First Slam Dunk 61.35G
[资料] 3000 套电影电视剧 LOGO 宣传片常用音效合集包
[安卓软件] 酷我音乐APP_v10.7.6.4 去广告破解豪华VIP版
[即时通讯] 微信PC版WeChat 3.9.9.43 多开防撤回绿色版
[安卓软件] Solid Explorer文件管理器APP 2.8.38 破解版
[云资源] 价值2万元的老男孩Python教程
[影视] 灌篮高手 WEB-DL版下载/Slam Dunk/スラムダンク/灌篮高手:THE FIRST/灌篮高手电影版 2022 The First Slam Dunk 61.35G
[云资源] 花了一千多元买的私人健身教程
[书库] 史上最全摄影书推荐(附700本PDF版打包下载)
[动画] 北斗神拳(1984) [两季合集] [MKV]
[资料] 抗战阵亡将士资料+续编
[电视剧] 三体 (2024) 全8集 网飞版本 中文字幕 合集
[纪录片] 河西走廊【10集 国语 中文字幕 1080P 10.8G MP4】
[电影] 2024年喜剧片·热辣滚烫 [mp4]
[影视] 铁爪 WEB-DL版下载 2023 The Iron Claw 23.48G
- 最新评论
-
我想看看mw2ddyy 评论于:04-26 好东西阿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
- 热门tag