【OS】实验二:内存管理

1,053 阅读3分钟

实验二:内存管理

使用 kmalloc 分配 1KB,8KB的内存,并打印指针地址

本个实验放在task2.1的文件夹中,创建文件夹

mkdir task2.1 task2.2

编写kmalloc.c文件和Makefile文件:

kmalloc.c

#include <linux/module.h>
#include <linux/slab.h>
MODULE_LICENSE("GPL");
unsigned char *kmallocmem1;
unsigned char *kmallocmem2;
static int __init mem_module_init(void)
{
    printk("Start kmalloc!\n");
    kmallocmem1 = (unsigned char*)kmalloc(1024, GFP_KERNEL);
    if (kmallocmem1 != NULL){
        printk(KERN_ALERT "kmallocmem1 addr = %lx\n", (unsigned long)kmallocmem1);
    }else{
        printk("Failed to allocate kmallocmem1!\n");
    }
    kmallocmem2 = (unsigned char *)kmalloc(8192, GFP_KERNEL);
    if (kmallocmem2 != NULL){
        printk(KERN_ALERT "kmallocmem2 addr = %lx\n", (unsigned long)kmallocmem2);
    }else{
        printk("Failed to allocate kmallocmem2!\n");
    }
    return 0;
}
static void __exit mem_module_exit(void)
{
    kfree(kmallocmem1);
    kfree(kmallocmem2);
    printk("Exit kmalloc!\n");
}
module_init(mem_module_init);
module_exit(mem_module_exit);

Makefile

ifneq ($(KERNELRELEASE),)
    obj-m := kmalloc.o
else
	KERNELDIR ?=/root/kernel-5.10.0-13.0.0
	PWD := $(shell pwd)
default:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
.PHONY:clean
clean:
	-rm *.mod.c *.o *.order *.symvers *.ko

然后编译make指令

make

加载模块

insmod kmalloc.ko

image-20211224221359952

查看加载的内容

dmesg | tail -n 3

模块的卸载及查看

rmmod kmalloc
dmesg | tail -n 4

image-20211224221527987

查看内核源码的文档 Documentation/arm64/memory.rst 可见,对应的内存布局如下:

image-20211224221917995

image-20211224222111988

使用vmalloc分别分配8KB、1MB、64MB的内存,打印指针地址

编写vmalloc.c文件和Makefile文件

vmalloc.c

#include <linux/module.h>
#include <linux/vmalloc.h>
MODULE_LICENSE("GPL");
unsigned char *vmallocmem1;
unsigned char *vmallocmem2;
unsigned char *vmallocmem3;
static int __init mem_module_init(void)
{
    printk("Start vmalloc!\n");
    vmallocmem1 = (unsigned char*)vmalloc(8192);
    if (vmallocmem1 != NULL){
        printk("vmallocmem1 addr = %lx\n", (unsigned long)vmallocmem1);
    }else{
        printk("Failed to allocate vmallocmem1!\n");
        }
    vmallocmem2 = (unsigned char*)vmalloc(1048576);
    if (vmallocmem2 != NULL){
        printk("vmallocmem2 addr = %lx\n", (unsigned long)vmallocmem2);
    }else{
        printk("Failed to allocate vmallocmem2!\n");
    }
    vmallocmem3 = (unsigned char*)vmalloc(67108864);
    if (vmallocmem3 != NULL){
        printk("vmallocmem3 addr = %lx\n", (unsigned long)vmallocmem3);
    }else{
        printk("Failed to allocate vmallocmem3!\n");
    }
    return 0;
}
static void __exit mem_module_exit(void)
{
    vfree(vmallocmem1);
    vfree(vmallocmem2);
    vfree(vmallocmem3);
    printk("Exit vmalloc!\n");
}
module_init(mem_module_init);
module_exit(mem_module_exit);

Makefile

ifneq ($(KERNELRELEASE),)
    obj-m := vmalloc.o
else
    KERNELDIR ?=/root/kernel-5.10.0-13.0.0
    PWD := $(shell pwd)
default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
.PHONY:clean
clean:
    -rm *.mod.c *.o *.order *.symvers *.ko

编译并加载模块

image-20211224223342743

image-20211224223409128

卸载及查看

image-20211224223443847

查看内核源码的文档 Documentation/arm64/memory.rst 可见,对应的内存布局如下:

image-20211224223813237

研讨

一、什么是内存泄漏、内存溢出、内存越界?

内存泄漏(memory leak):程序中己动态分配的内存未释放或无法释放,就产生了内存泄露。

内存溢出(out of memory):程序在申请内存时,没有足够的内存空间供其使用。

内存越界:是指程序向系统申请一块内存后,使用时超出申请范围。

二、分析程序

1、分析:下面这个程序是否会产生内存泄露、内存溢出或内存越界?

#include <stdlib.h>
void function_which_allocates(void) 
{
    float *a = malloc(sizeof(float) * 45);    // 分配包含45个浮点数的数组
    /* 使用数组a的代码 */
}
int main(void) 
{
function_which_allocates(); 
/* 指针a已经不存在了,所以包含45个浮点数的数组就不能被释放了,但这个数组还存在于内存中,因此就造成了内存泄露*/
}

分析:内存泄漏,己动态分配的内存未释放。 2、分析:下面这个程序是否会产生内存泄露、内存溢出或内存越界?

void func(char * input)
{
char buffer[16];
strcpy(buffer, input);
}
void main()
{
char longstring[256];
int i;
for( i = 0; i < 255; i++)
        longstring [i] = 'B';
func(longstring);
}

分析:内存越界:上述代码中,strcpy()直接将input中的内容copy到buffer中。而main函数中,传入input的长度是256,大于buffer的长度,造成buffer越界,使程序运行出错。

三、内存泄漏、内存溢出、内存越界的危害

1、内存漏洞的危害 (1)降低计算机的性能: 可用的内存越来越少,堆积后的后果就导致内存溢出; 导致其他应用程序无法使用内存 应用程序访问内存时,不停地产生缺页错误; 使得CPU不停地从磁盘上的swap空间读取页面数据,导致应用程序性能下降,cpu无法进行其他工作。 说明:现代计算机系统,当计算机程序终止运行时,它使用的内存会被释放掉;所以对于发生在这样的程序中的内存泄露就不会造成大的危害。

2、内存溢出的危害 (1)程序无法运行,有时候会自动关闭软件; (2)易遭受缓冲区溢出攻击/黑客攻击。

3、内存越界的危害 导致内存越界错误,程序向内存块中写入数据,超过内存块的边界,写到了其他内存对象中,导致覆盖了其他内存对象中的数据。