KDB支持单步调试功能(ARM架构)
0
?? 實踐發現KDB不支持step調試功能 (本文針對的是arm CotexA9架構,各種架構的實現方式不一樣,
?? X86的好像已經支持,不過本人沒有驗證過)
1
?? 首先看下要調試的代碼段
?? 1.1? C語言
?? int? testPara_7(int a, int b,int c,int d, int e,int f,int g)
?? {
??????? ?printk(KERN_ERR “hit one \n”);
??????? ?printk(KERN_ERR “hit two \n”);
??????? ?printk(KERN_ERR “hit three \n”);
???????? printk(KERN_ERR “hit four \n”);
??????? ?return 3;
?? }??
?? 1.2? 對應的匯編語言? (objdump -d vmlinux)
?? c0339bf8 <testPara_7>:
?? c0339bf8:?e1a0c00d ?mov?ip, sp
?? c0339bfc:?e92dd800 ?push?{fp, ip, lr, pc}
?? c0339c00:?e24cb004 ?sub?fp, ip, #4?; 0×4
?? c0339c04:?e59f0020 ?ldr?r0, [pc, #32]?; c0339c2c <testPara_7+0×34>
?? c0339c08:?eb05bbef ?bl?c04a8bcc <printk>
?? c0339c0c:?e59f001c ?ldr?r0, [pc, #28]?; c0339c30 <testPara_7+0×38>
?? c0339c10:?eb05bbed ?bl?c04a8bcc <printk>
?? c0339c14:?e59f0018 ?ldr?r0, [pc, #24]?; c0339c34 <testPara_7+0×3c>
?? c0339c18:?eb05bbeb ?bl?c04a8bcc <printk>
?? c0339c1c:?e59f0014 ?ldr?r0, [pc, #20]?; c0339c38 <testPara_7+0×40>
?? c0339c20:?eb05bbe9 ?bl?c04a8bcc <printk>
?? c0339c24:?e3a00003 ?mov?r0, #3?; 0×3
?? c0339c28:?e89da800 ?ldm?sp, {fp, sp, pc}
?? c0339c2c:?c060bd96 ?.word?0xc060bd96
?? c0339c30:?c060bda3 ?.word?0xc060bda3
?? c0339c34:?c060bdb0 ?.word?0xc060bdb0
?? c0339c38:?c060bdbf ?.word?0xc060bdbf
3
?? 通過分析匯編發現指令的地址都是以4的步長遞增的,這種情況就比較號解決了,
?? 不用去根據不同的匯編指令,改變PC的值。而只需要簡單的PC=PC+4即可。
4
?? 在Debug_core.c 增加函數如下:
?? 并在頭文件中聲明:? extern? void do_my_step(unsigned long addr);
void do_my_step(unsigned long addr)
{
???? int i=0;
???? for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++)
???? {
????????? if (kgdb_break[i].bpt_addr != addr)
????????????? continue;
??????? //找到地址相匹配的,修改其地址值
??????? ?kgdb_break[i].bpt_addr=kgdb_break[i].bpt_addr+4;
???????? kgdb_break[i].state = BP_SET;
????????? printk(KERN_ERR “i is %d??? kgdb_break[i].bpt_addr is %p\r\n”,i,? kgdb_break[i].bpt_addr);
???????? ?break;
??? }????????????? ??????????????????
}
5? 修改 kdb_bp.c 中的 kdb_handle_bp 函數如下:
?? static void kdb_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
{
????? ?if (KDB_DEBUG(BP))
?????????????? kdb_printf(“regs->ip = 0x%lx\n”, instruction_pointer(regs));
??????? //此處是新增的調用單步實現函數
???? ?do_my_step(instruction_pointer(regs));
???? ?/*
????? ? * Setup single step
??????? ?*/
????? ?kdb_setsinglestep(regs);
???? /*
????? ?* Reset delay attribute
?????? */
????? bp->bp_delay = 0;
??? ?bp->bp_delayed = 1;
}
6
? 實際應用,進入kdb模式后 ,(echo g > /proc/sysrq-trigger)
? 輸入ss即可實現單步模式(匯編級別的):
? kdb>bp c0339bf8??? (在testPara_7函數處設置一個斷點)
? kdb>go
? 之后kernel運行到此函數,系統進入KDB模式,就可以進行單步調試
? kdb>ss
? ….
? 與預想的一致,按兩次ss即可打印出一條語句:(可通過串口及minicom觀察)
? 如: hit one
???????????? hit two
???????????? …..
7
? 7.1? 總的來說實現了step功能,但是還是存在一些小bug
? 7.2? 有時間的話,希望能夠實現C語言級別的step(對我來說難度太大)
8
? kgdb_arch_handle_exception函數和自己實踐,ARM結構的GKDBb,并沒有
? 實現step調試功能。
? 曾試圖去實現kgdb的step功能,由于條件及能力限制沒能實現(
? kgdb需要用的一個串口通訊,調試本來也需要單獨一條,但是現在只有
? 一條共用的),
? int kgdb_arch_handle_exception(int exception_vector, int signo,
????????? int err_code, char *remcom_in_buffer,
????????? char *remcom_out_buffer,
????????? struct pt_regs *linux_regs)
? {
??????????? unsigned long addr;
?????????? ?char *ptr;
????????? ?switch (remcom_in_buffer[0]) {
???????????????????? ?case ‘D’:
????????????????????? case ‘k’:
???????????????????? ?case ‘c’:
????????????????????? ptr = &remcom_in_buffer[1];
???????????????????? ?if (kgdb_hex2long(&ptr, &addr))
??????????????????????????????????? linux_regs->ARM_pc = addr;
????????????????????? else if (compiled_break == 1)
?????????????????????????????????? ?linux_regs->ARM_pc += 4;
???????????????????? compiled_break = 0;
????????? return 0;
?}
return -1;
?}
?
轉載于:https://www.cnblogs.com/pangblog/p/3312929.html
總結
以上是生活随笔為你收集整理的KDB支持单步调试功能(ARM架构)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU1028——I gnatius a
- 下一篇: 【转】盛大创新院许式伟:影响我一生的五个