Linux内核编程:防御性编程学习

/*
 *Kernel  : Linux2.6.32.63
 *File    : \scripts\mod\modpost.h
            \scripts\mod\modpost.c
 *Author  : DavidLin
 *Date    : 2014-12-25pm
 *Email   : [email protected] or [email protected]
 *world   : the city of SZ, in China
 *Ver     : 000.000.001
 *history :     editor      time            do
 *          1)LinPeng       2014-12-25      created this file!
 *          2)
 */
  
/* Linux kernel code : modpost.h & modpost.c , author is someone, not me */
/* modpost.h */

#define NOFAIL(ptr)    do_nofail((ptr), #ptr)
void* do_nofail (void* ptr, const char* expr);

/* end of modpost.h */

/* modpost.c */

void* do_nofail(void* ptr, const char* expr)
{
    if(!ptr)
        fatal("modpost: Memory allocation failure:%s.\n", expr);
    return ptr;
}

static struct module* new_module(char* modname)
{
    struct module* mod;
    char *p, *s;

    mod = NOFAIL(malloc(sizeof(*mod)));
    memset(mod, 0, sizeof(*mod));
    p = NOFAIL(strdup(modname));

    /* strip trailing .o */
    s = strrchr(p, '.');
    if(s != NULL)
        if(strcmp(s, ".o") == 0)
            *s = '\0';
    /* add to list */
    mod->name = p;
    mod->gpl_compatible = -1;
    mod->next = modules;
    modules = mod;

    return mod;
}
/* end of modpost.c */

每个个体都需要重复演化,每个工程师也不例外。一般入门的时候,我们可能如下编写代码:

开始如同这步:

struct module* mod;
char *p, *s;

mod = malloc(sizeof(struct module));
memset(mod, 0, sizeof(struct module));
//未考虑mod == NULL

于是更进一步:

struct module* mod;
char *p, *s;

mod = malloc(sizeof(struct module));
if(NULL == mod) return NULL;
memset(mod, 0, sizeof(struct module));

如何再进一步?

是否每次使用malloc函数,都需要增加一句 if(NULL == ptr) return NULL;

是否可以优化? 是的,可以!

#define NOFAIL(ptr)    do_nofail((ptr), #ptr)
void* do_nofail (void* ptr, const char* expr);

    mod = NOFAIL(malloc(sizeof(*mod)));
    memset(mod, 0, sizeof(*mod));

1.非空封装已经封装在NOFAIL中,不仅编码工作减少,通过宏命名的自注释,可以很清楚知道该malloc期望的是只许成功,不许失败(当然只是期待),而且可以防止if(NULL == ptr)的偶然遗漏,更可更好的调试及维护代码;

2.使用sizeof(*mod)代替sizeof(struct module),使得mod类型变更时,并不会影响到具体函数,达到代码自适应效果。

还可以更进一步?

可以,消化吸收,根据项目具体应用情景,具体事物具体优化。

时间: 2024-12-29 07:36:50

Linux内核编程:防御性编程学习的相关文章

LINUX内核分析第四周学习总结——扒开应用系统的三层皮(上)

LINUX内核分析第四周学习总结——扒开应用系统的三层皮(上) 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.知识概要 (一)用户态.内核态和中断处理过程 (二)系统调用概述 系统调用概述和系统调用的三层皮 (三)使用库函数API和C代码中嵌入汇编代码触发同一个系统调用 使用库函数API获取系统当前时间 C代码中嵌入汇编代码的方法(复习) 使用C代码中嵌入汇编代码触发系统调

LINUX内核分析第一周学习总结——计算机是如何工作的

LINUX内核分析第一周学习总结——计算机是如何工作的 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.汇编代码的工作过程 1.实验过程 int a(int x) { return x + 2; } int b(int x) { return a(x); } int main(void) { return b(5) + 1; } 汇编代码如下: 2.代码分析 二.计算机工作的

《信息安全系统设计基础+Linux 内核分析》第一次学习总结

<信息安全系统设计基础+Linux 内核分析>第一次学习总结 教材学习内容总结 学习了<庖丁解牛>的第一章.知道的概念有: 存储程序计算机 = 冯诺依曼计算机,主要思想是:将程序存放在计算机存储器中,然后按存储器中的程序的首地址来执行程序的第一条指令,接下来就是一步一步按照程序中的编写好的指令来一步一步执行,直至程序结束. 冯诺依曼体系结构的要点如下图.底层是:RAM,ROM,运算器(ALU),控制器,寄存器. 由图可知:寄存器是在CPU中的,而RAM,ROM不是在CPU中的,它们

Linux内核中链表的学习

一.自己学习链表 数组的缺点:(1)数据类型一致:(2)数组的长度事先定好,不能灵活更改. 从而引入了链表来解决数组的这些缺点:(1)结构体解决多数据类型(2)链表的组合使得链表的长度可以灵活设置. 基本概念: 头结点: 这个节点是为了便于管理链表的节点,这个节点并不保存数据:虽然和其他节点一样,但是这个头结点是指向首节点的节点. 首节点: 第一个保存有效数据的节. 尾节点: 最后一个保存有效数据的节点 头指针: 头指针是指向头节点的指针. 单链表: 链表节点的数据结构定义: typedef s

linux内核list.h的学习

这个是学习linux内核的第一篇文章,所有的学习内容都在list.h的注释里面,直接上代码.

Linux内核设计第二周学习总结 完成一个简单的时间片轮转多道程序内核代码

陈巧然 原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.使用实验楼的虚拟机, 观察只有一个死循环的mykernel与时钟中断的关系 步骤:cd LinuxKernel/linux-3.9.4 qemu -kernel arch/x86/boot/bzImage 执行效果如下图 Paste_Image.png 现在查看mymain.c: Paste_Image.png 再查看myin

Linux内核分析——第二周学习笔记

20135313吴子怡.北京电子科技学院 chapter 1 知识点梳理 (一)计算机是如何工作的?(总结)——三个法宝 ①存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: ②函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能: enter pushl %ebp movl %esp,%ebp leave movl %ebp,%esp popl %ebp 函数参数传递机制和局部变量存储 ③中

LINUX内核分析第二周学习总结:操作系统是如何工作的?

马启扬 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.函数调用堆栈 1. 小结:计算机是怎样工作的 三个法宝:存储程序计算机.函数调用堆栈.中断机制. 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构. 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能.(函数参数传递

【转】Linux内核的ioctl函数学习

来源:Linux公社  http://www.linuxidc.com/Linux/2007-12/9623.htm 我这里说的ioctl函数是在驱动程序里的,因为我不知道还有没有别的场合用到了ioctl, 所以就规定了我们讨论的范围.为什么要写篇文章呢,是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. 一. 什么是ioctl. ioctl是设备驱动程序中对设备的I/O通道进行管理的函数.所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率

linux内核分析第二四学习报告

学生  黎静 课程内容 计算机三大法宝 • 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: • 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能: • 中断,多道程序操作系统的基点,没有中断机制程序只能从头一直运行结束才有可能开始运行其他程序. 一.函数调用堆栈 1.堆栈 堆栈式C语言程序运行时必须的一个记录调用路径和参数的空间.包括: 函数调用框架 传递参数 保存返回地址(如eax)