iT邦幫忙

0

linux 執行c檔求救

小弟我是資訊系學生,我今天在寫教授給的程式作業時
依照教授的ppt,一步步去改教授給的範例程式
作業要求很簡單就是顯示資訊而已,就不詳細介紹
然後做到以下這一步 如下圖
pic_1

最後到terminal 執行居然直接當掉 如下圖:
pic_2

原本是打完sudo insmod 123.ko 輸完密碼會出現

已砍掉

然後再輸sudo rmmod 會出現

error module 123 is in use

完整的忘記了 大概是這樣

但是第二次開始沒有 就一直是當掉的情況
我試著放在那邊給他跑 我去玩遊戲 玩了兩個小時還是這個樣子
/images/emoticon/emoticon02.gif

小弟的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

我後來有借同學的程式執行 同學的程式可以執行 我的卻不行 我覺得很神奇
想請教一下各路大神 為什麼會這樣?
而且我對比我程式和同學的沒差多少 只是設定變數名稱有差異
排版不好請多多見諒第一次發文/images/emoticon/emoticon41.gif

好酷歐,第一次看到include需要加linux w
DanSnow iT邦研究生 5 級 ‧ 2021-10-11 13:09:16 檢舉
他寫的是 kernel module ,是執行在跟作業系統同層級的程式,有點像是作業系統的外掛模組吧,驅動也算是一種
3
DanSnow
iT邦研究生 5 級 ‧ 2021-10-11 15:37:10
最佳解答

老實說你的 code 實在是有點亂,因為你的 init_module 有存取 NULL 導致 insmod 直接失敗了,這點你可以在 insmod 後用 sudo dmesg 確認

https://ithelp.ithome.com.tw/upload/images/20211011/20111802zokenXZWvy.png

只是接下來問題就來了,是哪邊存取到 NULL ,老實說我也不是很熟 kernel module 的 debug ,如果有更好的方法還請告訴我,首先我先參考了這篇 Stackoverflow,透過修改你的 Makefile 把 kernel module 加上了 debug info ,簡單來說就是開頭加上這個:

MY_CFLAGS += -g -DDEBUG
ccflags-y += ${MY_CFLAGS}
CC += ${MY_CFLAGS}

然後回去找 dmesg 裡的 stack trace
https://ithelp.ithome.com.tw/upload/images/20211011/20111802vciKVXrh21.png

可以看到程式最後執行到的位置是 init_module+0x164 ,這邊還是用相對位置,這在前面的那篇 Stackoverflow 裡也有提到,似乎是因為 Kernel Module 裡都用相對位置,所以這邊才會顯示成這樣,再來就是用 objdump -Sd <ko 檔> 反組譯來看 164 的位置到底是在哪邊

https://ithelp.ithome.com.tw/upload/images/20211011/20111802mFUJvwQwdC.png

到這邊就可以看出來是在初始化 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 啦,所以 person3name 根本沒分配到記憶體

Update:
知道有這樣的問題後剛剛又用眼睛掃了一遍,你的 person5 裡也混進了 person4

OscarCS iT邦新手 5 級 ‧ 2021-10-14 15:08:54 檢舉

非常感謝你的說明
恩 我知道我的code很亂,sorry。
因為我很懶,就按照教授給的範例,複製上去改而已
kernel module 我覺得你已經非常厲害
/images/emoticon/emoticon02.gif

OscarCS iT邦新手 5 級 ‧ 2021-10-14 15:29:22 檢舉

後來我改完你最後說的那些小錯誤就好了
不過還是非常感謝你的詳細說明
這次我學會了 下次就可以利用你這個方式去試試debug
我發現用terminal 執行程式 和 complier 執行真的差很多
編譯器會告訴你錯哪裡
terminal 就卡在那邊讓你發呆/images/emoticon/emoticon06.gif

1
海綿寶寶
iT邦大神 1 級 ‧ 2021-10-10 18:10:18

試試

sudo rmmod 123.ko

參考這篇看看

OscarCS iT邦新手 5 級 ‧ 2021-10-14 15:06:08 檢舉

他要求我輸入完密碼 就當掉 我沒辦法再打任何一個字/images/emoticon/emoticon02.gif

1
小魚
iT邦大師 1 級 ‧ 2021-10-10 18:32:21

他只是要你輸入密碼而已,
所以你密碼輸入了嗎?

OscarCS iT邦新手 5 級 ‧ 2021-10-14 15:04:18 檢舉

輸入完直接當掉/images/emoticon/emoticon02.gif

1
yun1231
iT邦新手 5 級 ‧ 2021-10-10 22:50:38

你可以去下載 gcc,一開始相對來說比較簡單,make 有點複雜~~~

OscarCS iT邦新手 5 級 ‧ 2021-10-14 15:07:02 檢舉

好 不過教授要求我們用make 我會自己在去學gcc

我要發表回答

立即登入回答