美文网首页内核LinuxLinux学习之路
IS_ERR PTR_ERR ERR_PTR原理小记

IS_ERR PTR_ERR ERR_PTR原理小记

作者: Jiafu | 来源:发表于2017-10-20 18:59 被阅读41次

今天在阅读Linux内核源代码的时候,看到了IS_ERR这个函数,觉得很有意思,深入地了解了一下,现把学习的结果记录一下。

IS_ERR宏的出现,是为了解决函数返回值的问题。由于C语言的函数返回值只能有一个,如果一个函数在正常执行后,返回一个指针,而在出现错误的时候,返回错误码,如何来实现这个需求呢?下面是一段示例代码:

void *p = NULL;

int err = func(&p);

if (err == 0)
{
    // p有效
}
else
{
    // p无效
}

可以看到,函数func返回的表示错误码,而指针则通过一个额外的参数来传递。我们能不能让func直接返回一个指针,如果失败了,让指针信息里包含错误码的信息呢?答案是可以的。

Linux支持的每个体系结构的虚拟地址空间都有从一个虚拟地址0到至少4KiB的区域,该区域没有任何有意义的信息。因此内核可以重用该地址范围来编码错误码。使用这种方法,总体来说,如果内核返回一个指针,那么有三种情况:合法指针、NULL指针和非法指针。

  • 合法指针:内核返回的指针一般是指向页面的边界(4K边界对齐),即ptr $0xfff == 0
  • 非法指针:这样的ptr的值不可能落在(0xfffff000, 0xffffffff)之间(这个区间是内核的高地址区间),而一般内核的出错代码也是一个小负数,在-1000到0之间,转换成unsigned long类型,正好在(0xfffff000, 0xffffffff)之间。因此可以用(unsigned long)ptr > (unsigned long)-MAX_ERRNO来判断内核函数返回值是一个有效的指针还是一个出错码。

与IS_ERR配套使用的宏还有PTR_ERR和ERR_PTR,分别用于将指针转换成错误码,和把错误码转换成指针。下面是从Linux源代码中找到的相关源代码,出自:include/linux/err.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

#ifndef __ASSEMBLY__

#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);
}

相关文章

  • IS_ERR PTR_ERR ERR_PTR原理小记

    今天在阅读Linux内核源代码的时候,看到了IS_ERR这个函数,觉得很有意思,深入地了解了一下,现把学习的结果记...

  • Linux 内核IS_ERR函数

    本文介绍Linux 4.4内核IS_ERR()函数。 文件:include/linux/err.h,定义如下: 一...

  • iOS分类的实现原理简记

    该文为分类原理的简单记录,总结自如下文章,感谢作者分享: iOS底层原理总结 iOS分类底层实现原理小记 1、分类...

  • AsyncTask源码学习总结

    前言 AsyncTask作为Android常用的异步消息机制,内部核心原理其实就是Handler。本小记不对Asy...

  • Webpack原理小记

    webpack是把项目当作一个整体,通过给定的一个主文件,webpack将从这个主文件开始找到你项目当中的所有依赖...

  • Web版扫雷开发小记(3)

    前篇: web版扫雷开发小记(1)web版扫雷开发小记(2)web版扫雷开发小记(3)web版扫雷开发小记(4) ...

  • 阅读 | 《微习惯》的行动指南

    前一篇的阅读小记简单地聊了聊“微习惯”的行动原理与从此延伸到我已经养成的“习惯”中可以适配的作为之后的生活样例(参...

  • 5.30日小易日精进

    重要三件事:1.吉他2.DXP 3.电子技术​ 小小记录: 今天把三门课程进行了学习,主要学习了: 自动控制原理:...

  • 小记

    小记

  • 参观中药房

    今天是孩子第一次参加安广小记者的活动,早早的起床,穿上小记者的马甲,带上小记者帽子,还有小记者的专用笔和...

网友评论

    本文标题:IS_ERR PTR_ERR ERR_PTR原理小记

    本文链接:https://www.haomeiwen.com/subject/mlovuxtx.html