03.應用程式調試

来源:http://www.cnblogs.com/Lwd-linux/archive/2017/02/02/6361275.html
-Advertisement-
Play Games

一、應用調試1:使用strace命令來跟蹤系統調用1.strace移植 cd /work/debug/strace-4.5.15 tar xjf strace-4.5.15.tar.bz2 cd strace-4.5.15 patch -p1 ../strace-fix-arm-bad-syscal ...



一、應用調試1:使用strace命令來跟蹤系統調用
1.strace移植

cd /work/debug/strace-4.5.15

tar xjf strace-4.5.15.tar.bz2

cd strace-4.5.15

patch -p1 ../strace-fix-arm-bad-syscall.patch

配置

./configure --host=arm-linux CC=arm-linux-gcc

編譯

make

會生成一個strace的可執行文件,將其複製到文件系統的/bin目錄下即可。

2.程式測試

strace -o log.txt ./firstdrvtest on

vi log.txt可以得到以下結果

 1 execve("./firstdrvtest", ["./firstdrvtest", "on"], [/* 7 vars */]) = 0
 2 uname({sys="Linux", node="(none)", ...}) = 0
 3 brk(0)                                  = 0x11000
 4 access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
 5 open("/etc/ld.so.cache", O_RDONLY)      = -1 ENOENT (No such file or directory)
 6 open("/lib/v4l/half/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory
 7 stat64("/lib/v4l/half", 0xbea5e4f0)     = -1 ENOENT (No such file or directory)
 8 open("/lib/v4l/libc.so.6", O_RDONLY)    = -1 ENOENT (No such file or directory)
 9 stat64("/lib/v4l", 0xbea5e4f0)          = -1 ENOENT (No such file or directory)
10 open("/lib/half/libc.so.6", O_RDONLY)   = -1 ENOENT (No such file or directory)
11 stat64("/lib/half", 0xbea5e4f0)         = -1 ENOENT (No such file or directory)
12 open("/lib/libc.so.6", O_RDONLY)        = 3
13 read(3, "\177ELF\1\1\1a\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\330o\1\000"..., 512) = 51
14 fstat64(3, {st_mode=S_IFREG|0755, st_size=1435660, ...}) = 0
15 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40
16 mmap2(NULL, 1150612, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x4
17 mprotect(0x40129000, 56980, PROT_NONE)  = 0
18 mmap2(0x40131000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRI
19 mmap2(0x40135000, 7828, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOU
20 close(3)                                = 0
21 open("/dev/xyz", O_RDWR)                = 3
22 write(3, "\1\0\0\0", 4)                 = 0
23 exit_group(0)                           = ?
測試程式

分析可知程式出錯都是由於沒有相對應的文件所造成的,而且使用這種方法調試比較直觀。


二、應用調試2:使用GDB來調試應用程式

編譯gdb,gdbserver
tar xjf gdb-7.4.tar.bz2
cd gdb-7.4/
./configure --target=arm-linux
make
把arm-linux-gdb複製到/bin目錄

cd gdb/gdbserver/
./configure --host=arm-linux
cp gdbserver /work/nfs_root/first_fs/bin

編譯要調試的應用,編譯時加上-g選項

調試:
1. 在ARM板上
gdbserver 192.168.1.17:2345 ./test_debug

2. 在PC上
/bin/arm-linux-gdb ./test_debug
輸入:target remote 192.168.1.17:2345
然後: 使用gdb命令來控製程序


另一種方法:
讓程式在開發板上直接運行,當它發生錯誤時,令它產生core dump文件
然後使用gdb根據core dump文件找到發生錯誤的地方
在ARM板上:
1. ulimit -c unlimited
2. 執行應用程式 : 程式出錯時會在當前目錄下生成名為core的文件

在PC上:
3. /bin/arm-linux-gdb ./test_debug ./core



三、應用調試3:配置內核輸出應用程式的段錯誤信息

arch/arm/mm/fault.c

__do_user_fault(struct task_struct *tsk, unsigned long addr,
        unsigned int fsr, unsigned int sig, int code,
        struct pt_regs *regs)
{
    struct siginfo si;

#ifdef CONFIG_DEBUG_USER   // 1. 配置內核
    if (user_debug & UDBG_SEGV) {
        printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
               tsk->comm, sig, addr, fsr);
        show_pte(tsk->mm, addr);
        show_regs(regs);
    }
#endif

2. uboot: set bootargs user_debug=0xff

set bootargs console=ttySAC0 root=/dev/nfs nfsroot=192.168.1.123:/work/nfs_root/first_fs ip=192.168.1.17 ipaddr=192.168.1.17 user_debug=0xff

3. 執行APP
./test_debug
a = 0x12
pgd = c04c8000
[00000000] *pgd=33d08031, *pte=00000000, *ppte=00000000

Pid: 772, comm:           test_debug
CPU: 0    Not tainted  (2.6.22.6 #1)
PC is at 0x84ac
LR is at 0x84d0
pc : [<000084ac>]    lr : [<000084d0>]    psr: 60000010
sp : bed9fe40  ip : bed9fe54  fp : bed9fe50
r10: 4013365c  r9 : 00000000  r8 : 00008514
r7 : 00000001  r6 : 000085cc  r5 : 00008568  r4 : bed9fec4
r3 : 00000012  r2 : 00000000  r1 : 00001000  r0 : 00000000
Flags: nZCv  IRQs on  FIQs on  Mode USER_32  Segment user
Control: c000717f  Table: 304c8000  DAC: 00000015
[<c002cd1c>] (show_regs+0x0/0x4c) from [<c0031a98>] (__do_user_fault+0x5c/0xa4)
 r4:c04a6840
[<c0031a3c>] (__do_user_fault+0x0/0xa4) from [<c0031d38>] (do_page_fault+0x1dc/0x20c)
 r7:c00261e0 r6:c0024cf8 r5:c04a6840 r4:ffffffec
[<c0031b5c>] (do_page_fault+0x0/0x20c) from [<c002b224>] (do_DataAbort+0x3c/0xa0)
[<c002b1e8>] (do_DataAbort+0x0/0xa0) from [<c002be48>] (ret_from_exception+0x0/0x10)
Exception stack(0xc3e7bfb0 to 0xc3e7bff8)
bfa0:                                     00000000 00001000 00000000 00000012
bfc0: bed9fec4 00008568 000085cc 00000001 00008514 00000000 4013365c bed9fe50
bfe0: bed9fe54 bed9fe40 000084d0 000084ac 60000010 ffffffff                   
 r8:00008514 r7:00000001 r6:000085cc r5:00008568 r4:c039bfc8
Segmentation fault

Stack:
00000000 becd3e64 becd3e54 000084d0 000084a0 00000000 becd3e78 becd3e68
C's sp                     return addr       B's sp

000084f0 000084c4 00000000 becd3e98 becd3e7c 00008554 000084e4 00000000
ret addr          A's sp                     ret addr          main's sp

00000012 becd3ec4 00000001 00000000 becd3e9c 40034f14 00008524 00000000
                                             ret addr          caller's sp
                                             對於動態鏈接,已經退出的程式不好確定動態庫的地址

00000000 0000839c 00000000 00000000 4001d594 000083c4 000085cc 4000c02c
becd3ec4 becd3f7b 00000000 becd3f88 becd3f92 becd3f99 becd3fad becd3fb8
becd3fdb becd3fe9 00000000 00000010 00000003 00000006 00001000 00000011
00000064 00000003 00008034 00000004 00000020 00000005 00000006 00000007
40000000 00000008 00000000 00000009 0000839c 0000000b 00000000 0000000c
00000000 0000000d 00000000 0000000e 00000000 00000017 00000000 0000000f
becd3f77 00000000 00000000 00000000 00000000 76000000 2e006c34 7365742f
65645f74 00677562 52455355 6f6f723d 4f480074 2f3d454d 61706900 3d726464
2e323931 2e383631 37312e31 52455400 74763d4d 00323031 48544150 62732f3d
2f3a6e69 2f727375 6e696273 69622f3a 752f3a6e 622f7273 53006e69 4c4c4548
69622f3d 68732f6e 44575000 2e002f3d 7365742f 65645f74 00677562 00000000

4. 反彙編app:
arm-linux-objdump -D test_debug > test_debug.dis

對於靜態鏈接的test_debug
PC is at 0x81e0
LR is at 0x8204
pc : [<000081e0>]    lr : [<00008204>]    psr: 60000010
sp : be93dc60  ip : be93dc74  fp : be93dc70
r10: 000085f4  r9 : 00008248  r8 : be93deb4
r7 : 00000001  r6 : 00000000  r5 : be93dd3e  r4 : 00000000
r3 : 00000012  r2 : 00000000  r1 : 00001000  r0 : 00000000
Flags: nZCv  IRQs on  FIQs on  Mode USER_32  Segment user

Stack:
00000000 be93dc84 be93dc74 00008204 000081d4 00000000 be93dc98 be93dc88
C'sp                       ret addr          B'sp

00008224 000081f8 00000000 be93dcb8 be93dc9c 00008288 00008218 00000000
ret addr          A'sp                       ret addr          main'sp

00000012 be93deb4 00000001 00000000 be93dcbc 000084ac 00008258 756e694c
                                             ret addr          __libc_start_main'sp

00000078 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 32393100
3836312e 312e312e 00000037 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 2e320000
32322e36 0000362e 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 23000000
54203335 4d206575 31207961 31322035 3a34303a 43203834 32205453 00323130
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
766d7261 006c7434 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
6f6e2800 0029656e 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 000080f8 00008680 00000000 be93deb4 be93df6a 00000000 be93df77
be93df81 be93df92 be93df99 be93dfad be93dfb8 be93dfdb be93dfe9 00000000
00000010 00000003 00000006 00001000 00000011 00000064 00000003 00008034
00000004 00000020 00000005 00000003 00000007 00000000 00000008 00000000
00000009 000080d0 0000000b 00000000 0000000c 00000000 0000000d 00000000
0000000e 00000000 00000017 00000000 0000000f be93df66 00000000 00000000
00000000 34760000 2f2e006c 74736574 6265645f 55006775 3d524553 746f6f72
444c4f00 3d445750 6f72702f 34372f63 4f480033 2f3d454d 61706900 3d726464
2e323931 2e383631 37312e31 52455400 74763d4d 00323031 48544150 62732f3d
2f3a6e69 2f727375 6e696273 69622f3a 752f3a6e 622f7273 53006e69 4c4c4548
69622f3d 68732f6e 44575000 2e002f3d 7365742f 65645f74 00677562 00000000

四、應用調試4:自製系統調用、編寫進程查看器

把29th_app_system_call\kernel里的文件複製到內核目錄
syscalls.h    ==> include/linux
read_write.c  ==> fs/
calls.S       ==> arch/arm/kernel

五、應用調試5:編寫輸入模擬器
1. 產品要經過測試才能發佈,一般都是人工操作,比如手機觸摸屏、遙控器
2. 操作過程中發現錯誤,要再次復現,找到規律,修改程式
3. 能否在驅動程式里把所有的操作記錄下來,存為文件
   當出錯時,可以通過文件里的數據來"復現"輸入
   
   input_event
   


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 當創建一個表時,需要為表的各個列指定數據類型,Oracle的數據類型主要有5種,字元類型、數值類型、日期時間類型、LOB類型和偽列。 一、字元類型 1、CHAR類型 定長字元串,長度為1~2000位元組,如果定義時未指定大小,預設為1,使用時,若存儲的值大小小於指定的長度,則用空格填充剩餘長度, 若大 ...
  • 當你開始編寫 Apache Spark 代碼或者瀏覽公開的 API 的時候,你會遇到各種各樣術語,比如transformation,action,RDD 等等。 瞭解到這些是編寫 Spark 代碼的基礎。 同樣,當你任務開始失敗或者你需要透過web界面去瞭解自己的應用為何如此費時的時候,你需要去瞭解 ...
  • 非電腦專業,導師基本做單片機的項目,所以基本靠自學,經過兩年實踐,證明該學習路線基本可靠 所以分亨給對嵌入式Linux感興趣的學弟學妹 要學的東西真的很多,這裡僅提供入門之道,分為基礎知識和實踐兩個部分 第一部分,專業知識 C語言學習 《C和指針》 《C專家編程》 《C陷阱與缺陷》 上面三本書,認 ...
  • 1、安裝kernel-debuginfo-common 和 kernel-debuginfo(下載地址:http://debuginfo.centos.org/6/x86_64/),安裝之前,先通過uname -r 確認內核版本 [root@xxxmysqlbkuat01 ~]# uname -r ...
  • 1.讀readme獲取信息 1.1 由Building the Software可知,需修改頂層makefile,指定架構和編譯器 ifeq ($(HOSTARCH),$(ARCH)) CROSS_COMPILE ?= arm-linux- endif ARCH = arm CROSS_COMPIL ...
  • 本文地址 分享提綱: 1. shell中的函數 2. shell中的數組 1. shell中的函數 1.1)【定義shell函數(define function)】 說明: 1、可以帶function fun() 定義,也可以直接fun() 定義,不帶任何參數。 2、參數返回,可以顯示加:retur ...
  • 七. 構建臨時系統 1. 通用編譯指南 a. 確認是否正確設置了 LFS 環境變數 b. 假定你已經正確地設置了宿主系統需求和符號鏈接 c. 對於每個軟體包: (1). 確保解壓軟體包時你使用的是 lfs 用戶 (2). 除非特別說明,刪除解壓出來的目錄和所有編譯過程中生成的 build 目錄 2. ...
  • GPS模塊使用串口通信,那麼它的的數據處理本質上還是串口通信處理,只是GPS模塊的輸出的有其特定的格式,需要字元串處理邏輯來解析其含義。如何高效的處理從GPS模塊接收到的數據幀,是GPS驅動設計的重點,本文使用狀態機的思想來處理GPS輸出的串口數據流,相對於定時從串口環形bufer取數據包然後依次解... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...