小弟我是資訊系學生,我今天在寫教授給的程式作業時
依照教授的ppt,一步步去改教授給的範例程式
作業要求很簡單就是顯示資訊而已,就不詳細介紹
然後做到以下這一步 如下圖
最後到terminal 執行居然直接當掉 如下圖:
原本是打完sudo insmod 123.ko 輸完密碼會出現
已砍掉
然後再輸sudo rmmod 會出現
error module 123 is in use
完整的忘記了 大概是這樣
但是第二次開始沒有 就一直是當掉的情況
我試著放在那邊給他跑 我去玩遊戲 玩了兩個小時還是這個樣子
小弟的c檔案程式碼(檔案名叫123.c)
#include <linux/string.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/slab.h>
struct birthday{
int day;
int month;
int year;
char *name;
char *NID;
char *gender;
struct list_head list;
};
static LIST_HEAD(birthday_list);
//進入kernel module
int simple_init(void){
struct birthday *ptr;
struct birthday *person, *person2,*person3,*person4,*person5;
person = kmalloc(sizeof(*person), GFP_KERNEL);
person->day=22;
person->month=7;
person->year=2018;
person->name=kmalloc(sizeof("Jane"), GFP_KERNEL);
strcpy(person->name, "Jane");
person->NID=kmalloc(sizeof("D08001"), GFP_KERNEL);
strcpy(person->NID, "D08001");
person2 = kmalloc(sizeof(*person2), GFP_KERNEL);
person2->day=10;
person2->month=8;
person2->year=2001;
person2->name=kmalloc(sizeof("Ray"), GFP_KERNEL);
strcpy(person2->name, "Ray");
person2->NID=kmalloc(sizeof("D0812345"), GFP_KERNEL);
strcpy(person2->NID, "D0812345");
person3 = kmalloc(sizeof(*person3), GFP_KERNEL);
person3->day=4;
person3->month=3;
person3->year=2018;
person2->name=kmalloc(sizeof("Lacey"), GFP_KERNEL);
strcpy(person3->name, "Lacey");
person3->NID=kmalloc(sizeof("D08003"), GFP_KERNEL);
strcpy(person3->NID, "D08003");
person4 = kmalloc(sizeof(*person4), GFP_KERNEL);
person4->day=4;
person4->month=4;
person4->year=2018;
person4->name=kmalloc(sizeof("Tom"), GFP_KERNEL);
strcpy(person4->name, "Tom");
person4->NID=kmalloc(sizeof("D08004"), GFP_KERNEL);
strcpy(person4->NID, "D08004");
person5 = kmalloc(sizeof(*person5), GFP_KERNEL);
person5->day=4;
person5->month=5;
person5->year=2018;
person5->name=kmalloc(sizeof("Stuart"), GFP_KERNEL);
strcpy(person5->name, "Stuart");
person4->NID=kmalloc(sizeof("D08005"), GFP_KERNEL);
strcpy(person5->NID, "D08005");
INIT_LIST_HEAD(&person->list);
list_add_tail(&person->list,&birthday_list);
list_add_tail(&person2->list,&birthday_list);
list_add_tail(&person3->list,&birthday_list);
list_add_tail(&person4->list,&birthday_list);
list_add_tail(&person5->list,&birthday_list);
printk(KERN_INFO "loading module\n");
list_for_each_entry(ptr,&birthday_list,list){
printk(KERN_ALERT "Name: %s,\t",ptr->name);
printk(KERN_ALERT "NID: %s,\t",ptr->NID);
printk(KERN_ALERT "Birthday: %d/%d/%d\t",ptr->month,ptr->day,ptr->year);
}
return 0;
}
//離聞 kernel module
void simple_exit(void){
struct birthday *ptr , *next;
list_for_each_entry_safe(ptr, next, &birthday_list, list){
list_del(&ptr->list);
kfree(ptr);
}
printk(KERN_INFO "Removing module\n");
}
//進入或離開knel
module_init(simple_init);
module_exit(simple_exit);
再來是makefile 的內容
obj-m += 123.o
KDIR = /usr/src/linux-headers-4.15.0-112-generic
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
我後來有借同學的程式執行 同學的程式可以執行 我的卻不行 我覺得很神奇
想請教一下各路大神 為什麼會這樣?
而且我對比我程式和同學的沒差多少 只是設定變數名稱有差異
排版不好請多多見諒第一次發文
老實說你的 code 實在是有點亂,因為你的 init_module 有存取 NULL 導致 insmod 直接失敗了,這點你可以在 insmod 後用 sudo dmesg
確認
只是接下來問題就來了,是哪邊存取到 NULL ,老實說我也不是很熟 kernel module 的 debug ,如果有更好的方法還請告訴我,首先我先參考了這篇 Stackoverflow,透過修改你的 Makefile 把 kernel module 加上了 debug info ,簡單來說就是開頭加上這個:
MY_CFLAGS += -g -DDEBUG
ccflags-y += ${MY_CFLAGS}
CC += ${MY_CFLAGS}
然後回去找 dmesg 裡的 stack trace
可以看到程式最後執行到的位置是 init_module+0x164
,這邊還是用相對位置,這在前面的那篇 Stackoverflow 裡也有提到,似乎是因為 Kernel Module 裡都用相對位置,所以這邊才會顯示成這樣,再來就是用 objdump -Sd <ko 檔>
反組譯來看 164 的位置到底是在哪邊
到這邊就可以看出來是在初始化 person3 時當了,回去看你的 code
person3 = kmalloc(sizeof(*person3), GFP_KERNEL);
person3->day=4;
person3->month=3;
person3->year=2018;
person2->name=kmalloc(sizeof("Lacey"), GFP_KERNEL);
strcpy(person3->name, "Lacey");
person3->NID=kmalloc(sizeof("D08003"), GFP_KERNEL);
strcpy(person3->NID, "D08003");
你 person3
中混進了一個 person2
啦,所以 person3
的 name
根本沒分配到記憶體
Update:
知道有這樣的問題後剛剛又用眼睛掃了一遍,你的 person5
裡也混進了 person4
你可以去下載 gcc,一開始相對來說比較簡單,make 有點複雜~~~