Linux環(huán)境下的GDB調(diào)試方法
https://blog.csdn.net/horotororensu/article/details/82256832
網(wǎng)上很多,這篇比較全,建議收藏或自行總結(jié)。
GOT表和PLT表知識詳解
https://blog.csdn.net/qq_18661257/article/details/54694748
關(guān)于fork函數(shù)和execl函數(shù)
fork函數(shù)的特性。fork被調(diào)用一次,卻能夠返回兩次,它可能有三種不同的返回值:
1)在父進(jìn)程中,fork返回新創(chuàng)建子進(jìn)程的進(jìn)程ID;
2)在子進(jìn)程中,fork返回0;
3)如果出現(xiàn)錯(cuò)誤,fork返回一個(gè)負(fù)值;
在fork函數(shù)執(zhí)行完畢后,如果創(chuàng)建新進(jìn)程成功,則出現(xiàn)兩個(gè)進(jìn)程,一個(gè)是子進(jìn)程,一個(gè)是父進(jìn)程。在子進(jìn)程中,fork函數(shù)返回0,在父進(jìn)程中,fork返回新創(chuàng)建子進(jìn)程的進(jìn)程ID。我們可以通過fork返回的值來判斷當(dāng)前進(jìn)程是子進(jìn)程還是父進(jìn)程。
execl函數(shù)說明
int execl(const char * path,const char * arg,....);
execl()用來執(zhí)行參數(shù)path字符串所代表的文件路徑,
接下來的參數(shù)代表執(zhí)行該文件時(shí)傳遞過去的argv(0)、argv[1]……,
最后一個(gè)參數(shù)必須用空指針(NULL)作結(jié)束。*/
MODULE_LICENSE("GPL")
模塊的許可證聲明
從2.4.10版本內(nèi)核開始,模塊必須通過MODULE_LICENSE宏聲明此模塊的許可證,否則在加載此模塊時(shí),會收到內(nèi)核被污染 “kernel tainted” 的警告。從linux/module.h文件中可以看到,被內(nèi)核接受的有意義的許可證有 “GPL”,“GPL v2”,“GPL and additional rights”,“Dual BSD/GPL”,“Dual MPL/GPL”,“Proprietary”。
在同時(shí)支持2.4與2.6內(nèi)核的設(shè)備驅(qū)動中,模塊可按如下方式聲明自己的許可證。
適用于2.4與2.6內(nèi)核的模塊許可證聲明模板
MODULE_LICENSE(“GPL”);
獲得內(nèi)核函數(shù)地址的四種方法
1、從 System.map 文件中直接得到地址
grep sys_read /boot/System.map
2、使用 nm 命令讀取 vmlinux 的信息
nm /usr/lib/debug/boot/vmlinux-4.4.0-72-generic | grep sys_read
3、從 /proc/kallsyms 文件獲得地址
cat /proc/kallsyms | grep perf_trace_do_sys_open
4、使用內(nèi)核函數(shù)接口
使用 kallsyms_lookup_name( )
該函數(shù)在 kernel/kallsyms.c 文件中定義的, 要使用它必須啟用 CONFIG_KALLSYMS 編譯內(nèi)核.
kallsyms_lookup_name( ) 接受一個(gè)字符串格式內(nèi)核函數(shù)名, 返回那個(gè)內(nèi)核函數(shù)的地址.
kallsyms_lookup_name("函數(shù)名");
更多詳細(xì)介紹:https://blog.csdn.net/gatieme/article/details/78310036
CR0的宏,網(wǎng)上扒的
#define CLEAR_CR0 asm ("pushl %eax\n\t" \
"movl %cr0, %eax\n\t" \
"andl $0xfffeffff, %eax\n\t" \
"movl %eax, %cr0\n\t" \
"popl %eax");
#define SET_CR0 asm ("pushl %eax\n\t" \
"movl %cr0, %eax\n\t" \
"orl $0x00010000, %eax\n\t" \
"movl %eax, %cr0\n\t" \
"popl %eax");
作用:用于根據(jù)一個(gè)結(jié)構(gòu)體的一個(gè)成員獲取這個(gè)結(jié)構(gòu)體的首地址。(根據(jù)成員指針獲取父結(jié)構(gòu)體變量指針。)
關(guān)于函數(shù)IS_ERR()
IS_ERR()來判斷內(nèi)核函數(shù)的返回值是不是一個(gè)有效的指針。
vim命令查看內(nèi)核源碼
shell腳本
#!/bin/sh
DIR=`pwd`
ctags -R --languages=C,C++ --c++-kinds=+p --fields=+iaS --extra=+q $DIR
find $DIR -name "*.h" -o -name "*.c" -o -name "*.cc" > cscope.files
cscope -bkq -i cscope.files
運(yùn)行腳本
在內(nèi)核源碼目錄運(yùn)行該腳本
說明:建立tag需要點(diǎn)時(shí)間,請耐心等待。
然后,用gvim快速查找函數(shù)、結(jié)構(gòu)體等的定義與聲明。
vim [arguments] -t tag edit file where tag is defined
例如:查找init_rootfs函數(shù)的定義,使用gvim -t init_rootfs,如果定義只有一處,它會立即自動打開這個(gè)文件,并跳轉(zhuǎn)到結(jié)構(gòu)體上,否則會提示你選擇哪個(gè)文件的哪一處定義。
查看ubuntu系統(tǒng)的版本信息
打開終端輸入
cat /proc/version
顯示如下
Linux version 4.10.0-28-generic (buildd@lgw01-12) linux內(nèi)核版本號
gcc version 5.4.0 gcc編譯器版本號
Ubuntu 5.4.0-6ubuntu1 Ubuntu版本號
打開終端輸入
uname -a
顯示linux的內(nèi)核版本和系統(tǒng)是多少位的:X86_64代表系統(tǒng)是64位的。
打開終端輸入
lsb_release -a
顯示如下
Distributor ID: Ubuntu //類別是ubuntu
Description: Ubuntu 16.04.3 LTS //16年3月發(fā)布的穩(wěn)定版本,LTS是Long Term Support:長時(shí)間支持版本,支持周期長達(dá)三至五年
Release: 16.04 //發(fā)行日期或者是發(fā)行版本號
Codename: xenial //ubuntu的代號名稱