當前位置:編程學習大全網 - 源碼下載 - 如何確定 dbx 地址 terminated by signal SEGV no mapping

如何確定 dbx 地址 terminated by signal SEGV no mapping

使用 dbx 調試程序

可能出於下列原因之壹調試程序:

為了確定程序在何處以及為何導致崩潰。確定崩潰原因的方法包括:

在 dbx 中運行程序。dbx 會報告崩潰的發生位置。

檢查核心轉儲文件並查看棧跟蹤(請參見檢查核心轉儲文件 and 查看調用棧)。

為了確定程序為何給出錯誤結果。其方法包括:

設置用於停止執行的斷點,以便可以檢查程序的狀態以及查看變量值(請參見設置斷點和檢查變量)。

按壹次執行壹個源代碼行的方式執行代碼來監視程序狀態的變化情況(請參見單步執行程序)。

為了查找內存泄漏或內存管理問題。執行運行時檢查可以檢測運行時錯誤(如,內存訪問錯誤和內存泄漏錯誤),以及監視內存使用(請參見查找內存訪問問題和內存泄漏)。

檢查核心轉儲文件

要確定程序發生崩潰的位置,可能需要檢查核心轉儲文件,即程序崩潰時的程序內存映像。可使用 where 命令(請參見where 命令)確定程序在轉儲核心時的執行位置。

註 - dbx 無法像對待本機代碼那樣通過核心轉儲文件來指明 Java 應用程序的狀態。

要調試核心轉儲文件,請鍵入:

$ dbx program_name core

$ dbx - core

在下面的示例中,程序因段故障和轉儲核心而崩潰。用戶啟動 dbx 並裝入核心轉儲文件。然後使用 where 命令顯示棧跟蹤,其中顯示在 foo.c 文件的第 9 行發生崩潰。

% dbx a.out core

Reading a.out

core file header read successfully

Reading ld.so.1

Reading libc.so.1

Reading libdl.so.1

Reading libc_psr.so.1

program terminated by signal SEGV (no mapping at the fault address)

Current function is main

9 printf("string ’%s’ is %d characters long\n", msg, strlen(msg));

(dbx) where

[1] strlen(0x0, 0x0, 0xff337d24, 0x7efefeff, 0x, 0xff0000), at

0xff2b6dec

=>[2] main(argc = 1, argv = 0xffbef39c), line 9 in "foo.c"

(dbx)

有關調試核心轉儲文件的更多信息,請參見調試核心轉儲文件。有關使用調用棧的更多信息,請參見查看調用棧。

註 - 如果程序與***享庫動態鏈接,最好在創建核心轉儲文件的操作環境中調試該文件。有關如何調試在不同的操作環境中創建的核心轉儲文件的信息,請參見調試不匹配的核心轉儲文件。

設置斷點

斷點是程序中要暫時停止程序的執行並讓 dbx 進行控制的位置。在程序內懷疑存在錯誤之處設置斷點。如果程序崩潰,請確定崩潰的發生位置,然後在這部分代碼前設置斷點。

程序在斷點處停止時,便可以檢查程序的狀態和變量值。使用 dbx 可以設置多種類型的斷點(請參見使用 Ctrl+C 停止進程)。

最簡單的斷點類型就是停止斷點。可以設置用於在函數或過程中停止的停止斷點。例如,要在調用 main 函數時停止:

(dbx) stop in main

(2) stop in main

有關 stop in 命令的更多信息,請參見在函數中設置 stop 斷點和stop 命令。

也可以設置用於在源代碼的特定行處停止的停止斷點。例如,要在源文件 t.c 中的第 13 行處停止:

(dbx) stop at t.c:13

(3) stop at “t.c”:13

有關 stop at 命令的更多信息,請參見在源代碼行設置 stop 斷點和stop 命令。

可以使用 file 命令設置當前文件並使用 list 命令列出要在其中停止的函數來確定要停止在那裏的行。然後使用 stop at 命令在源代碼行設置斷點:

(dbx) file t.c

(dbx) list main

10 main(int argc, char *argv[])

11 {

12 char *msg = "hello world\n";

13 printit(msg);

14 }

(dbx) stop at 13

(4) stop at “t.c”:13

要使程序在斷點處停止後繼續執行,請使用 cont 命令(請參見繼續執行程序和cont 命令)。

要獲取所有當前斷點的列表,請使用 status 命令:

(dbx) status

(2) stop in main

(3) stop at "t.c":13

現在如果運行程序,程序將在第壹個斷點處停止:

(dbx) run

stopped in main at line 12 in file "t.c"

12 char *msg = "hello world\n";

單步執行程序

程序在斷點處停止後,可能希望按壹次執行壹個源代碼行的方式執行程序,在此時比較程序的實際狀態與預期狀態。可以使用 step 和 next 命令來執行此操作。這兩個命令都是執行程序的壹個源代碼行,當執行完相應行時即停止。但在處理包含函數調用的源代碼行時有所差別:step 命令步入函數,而 next 命令步過函數。

step up 命令會壹直執行,直至當前函數將控制權返回給調用它的函數為止。

step to 命令會嘗試步入當前源代碼行中的指定函數;如果未指定任何函數,則嘗試步入由當前源代碼行的匯編代碼確定調用的最後壹個函數。

某些函數(特別是 printf 之類的庫函數)可能未使用 -g 選項編譯,因此 dbx 無法步入這些函數。在這種情況下,step 和 next 執行功能相似。

以下示例說明如何使用 step 和 next 命令以及在設置斷點中設置的斷點。

(dbx) stop at 13

(3) stop at "t.c":13

(dbx) run

Running: a.out

stopped in main at line 13 in file "t.c"

13 printit(msg);

(dbx) next

Hello world

stopped in main at line 14 in file "t.c"

14 }

(dbx) run

Running: a.out

stopped in main at line 13 in file "t.c"

13 printit(msg);

(dbx) step

stopped in printit at line 6 in file "t.c"

6 printf("%s\n", msg);

(dbx) step up

Hello world

printit returns

stopped in main at line 13 in file "t.c"

13 printit(msg);

(dbx)

有關單步執行程序的更多信息,請參見單步執行程序。有關 step 和 next 命令的更多信息,請參見step 命令和next 命令。

查看調用棧

調用棧表示所有當前處於活動狀態的例程,即那些已被調用但尚未返回至各自調用方的例程。在該棧中,函數及其參數按其調用順序存放。棧跟蹤顯示程序流中執行停止位置及執行到達此點的過程。它提供了有關程序狀態的最簡明的描述。

要顯示棧跟蹤,請使用 where 命令:

(dbx) stop in printf

(dbx) run

(dbx) where

[1] printf(0x10938, 0x20a84, 0x0, 0x0, 0x0, 0x0), at 0xef

=>[2] printit(msg = 0x20a84 "hello world\n"), line 6 in "t.c"

[3] main(argc = 1, argv = 0xefffe93c), line 13 in "t.c"

(dbx)

對於使用 -g 選項編譯的函數,參數名及其類型是已知的,因此會顯示精確的值。對於無調試信息的函數,顯示的參數值是十六進制數。這些數字未必都有意義。例如,在上述棧跟蹤中,幀 1 所示為 SPARC 輸入寄存器 $i0 至 $i5 的內容,但僅寄存器 $i0 至 $i1 的內容有意義,因為只有兩個參數傳遞到單步執行程序所示的示例中的 printf。

可以在未使用 -g 選項編譯的函數中停止。在此類函數中停止時,dbx 在棧內向下搜索其函數是使用 -g 選項編譯的第壹幀(本例中為 printit()),並為其設置當前作用域(請參見程序作用域)。這用箭頭符號 (=>) 表示。

有關調用棧的更多信息,請參見效率方面的考慮。

檢查變量

雖然棧跟蹤可能包含足夠的信息,可以完全表明程序的狀態,但仍可能需要查看更多變量的值。print 命令可以求表達式的值,並根據表達式的類型輸出值。以下示例中例舉了幾個簡單的 C 表達式:

(dbx) print msg

msg = 0x20a84 "Hello world"

(dbx) print msg[0]

msg[0] = ’h’

(dbx) print *msg

*msg = ’h’

(dbx) print msg

msg = 0xefffe8b4

可以使用數據更改斷點跟蹤變量和表達式的值何時發生變化(請參見設置數據更改斷點)。例如,要在變量計數值更改時停止執行,請鍵入:

(dbx) stop change count

查找內存訪問問題和內存泄漏

運行時檢查由兩部分組成: 內存訪問檢查及內存使用和泄露檢查。訪問檢查將檢查被調試應用程序是否不當使用了內存。內存使用和泄露檢查包括跟蹤所有仍存在的堆空間,然後在需要時或程序終止時,掃描可用數據空間以及識別無引用的空間。

可以使用 check 命令啟用內存訪問檢查及內存使用和泄露檢查。要僅啟用內存訪問檢查,請鍵入:

(dbx) check -access

要啟用內存使用和內存泄漏檢查,請鍵入:

(dbx) check -memuse

啟用所需的運行時檢查類型後,運行程序。程序正常運行,但速度很慢,因為每次進行內存訪問前都要檢查其有效性。如果 dbx 檢測到無效訪問,便會顯示錯誤的類型和位置。此時,可以使用 dbx 命令(如 where 命令)獲取當前棧跟蹤,也可以使用 print 命令檢查變量。

註 - 不能對使用 Java 代碼和 C JNI 代碼或 C++ JNI 代碼混編的應用程序使用運行時檢查。

  • 上一篇:Drawable子類之——LayerDrawable (圖層疊加)
  • 下一篇:小米實錘!這種App會偷偷刪除手機資料
  • copyright 2024編程學習大全網