gdb無源碼調試
㈠ gdb調試命令是什麼
gdb調試命令如下:
1、啟動gdb
$gdb
這樣可以和gdb進行交互了。
2、啟動gdb,並且分屏顯示源代碼
$gdb -tui
這樣,使用了'-tui'選項,啟動可以直接將屏幕分成兩個部分,上面顯示源代碼,比用list方便多了。這時候使用上下方向鍵可以查看源代碼,想要命令行使用上下鍵就用[Ctrl]n和[Ctrl]p。
3、啟動gdb調試指定程序app
$gdb app
這樣就在啟動gdb之後直接載入了app可執行程序,需要注意的是,載入的app程序必須在編譯的時候有gdb調試選項,例如'gcc -g app app.c',注意,如果修改了程序的源代碼,但是沒有編譯,那麼在gdb中顯示的會是改動後的源代碼,但是運行的是改動前的程序,這樣會導致跟蹤錯亂的。
4、啟動程序之後,再用gdb調試
$gdb <program> <PID>
這里,<program>是程序的可執行文件名,<PID>是要調試程序的PID.如果你的程序是一個服務程序,那麼你可以指定這個服務程序運行時的進程ID。gdb會自動attach上去,並調試他。program應該在PATH環境變數中搜索得到。
5、啟動程序之後,再啟動gdb調試
$gdb <PID>
這里,程序是一個服務程序,那麼你可以指定這個服務程序運行時的進程ID,<PID>是要調試程序的PID.這樣gdb就附加到程序上了,但是現在還沒法查看源代碼,用file命令指明可執行文件就可以顯示源代碼了。
㈡ GDB調試無法載入源碼
你使用Makefile編譯調試的吧。
注意Makefile的寫法,一個空格也會造成錯誤的。
在編譯的代碼中添加 -g 和 -Wall 。-g是為了GDB調試用的,-Wall可以顯示全部的警告,對你分析程序很有好處。
這個Segemental fault 是段錯誤,造成這個錯誤的原因有很多,可能是內存 或者 棧溢出,出現這個錯誤需要功過GDB反復調試,查看錯誤原因。
㈢ 如何使用gdb調試android程序
用gdb調試動態鏈接庫
大家都知道在 linux 可以用 gdb 來調試應用程序,當然前提是用 gcc 編譯程序時要加上 -g 參數。
我這篇文章里將討論一下用 gdb 來調試動態鏈接庫的問題。
首先,假設我們准備這樣的一個動態鏈接庫:
引用:
庫名稱是: ggg
動態鏈接庫文件名是: libggg.so
頭文件是: get.h
提供這樣兩個函數調用介面:
int get ();
int set (int a);
要生成這樣一個動態鏈接庫,我們首先編寫這樣一個頭文件:
/************關於本文檔********************************************
*filename: get.h
*********************************************************************/
int get ();
int set (int a);
然後准備這樣一個生成動態鏈接庫的源文件:
/************關於本文檔********************************************
*filename: get.cpp
*********************************************************************/
#include
#include "get.h"
static int x=0;
int get ()
{
printf ("get x=%d\n", x);
return x;
}
int set (int a)
{
printf ("set a=%d\n", a);
x = a;
return x;
}
然後我們用 GNU 的 C/C++ 編譯器來生成動態鏈接庫,編譯命令如下:
引用:
g++ get.cpp -shared -g -DDEBUG -o libggg.so
這樣我們就准備好了動態鏈接庫了,下面我們編寫一個應用程序來調用此動態鏈接庫,源代碼如下:
/************關於本文檔********************************************
*filename: pk.cpp
*********************************************************************/
#include
#include "get.h"
int main (int argc, char** argv)
{
int a = 100;
int b = get ();
int c = set (a);
int d = get ();
printf ("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d);
return 0;
}
編譯此程序用下列命令,如果已經把上面生成的 libggg.so 放到了庫文件搜索路徑指定的文件目錄,比如 /lib 或 /usr/lib 之類的,就用下面這條命令:
引用:
g++ pk.cpp -o app -Wall -g -lggg
否則就用下面這條命令:
引用:
g++ pk.cpp -o app -Wall -g -lggg -L`pwd`
下面我們就開始調試上面命令生成的 app 程序吧。如果已經把上面生成的 libggg.so 放到了庫文件搜索路徑指定的文件目錄,比如 /lib 或 /usr/lib 之類的,調試就順利完成,如下:
引用:
#gdb ./app
GNU gdb 6.4-debian
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show ing" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) b main /* 這是在程序的 main 處設置斷點 */
Breakpoint 1 at 0x804853c: file pk.cpp, line 7.
(gdb) b set /* 這是在程序的 set 處設置斷點 */
Function "set" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y /* 這里必須選擇 y 調試程序才會跟蹤到動態鏈接庫內部去 */
Breakpoint 2 (set) pending.
(gdb) run /* 開始運行我們的程序,直到遇見斷點時暫停 */
Starting program: /data/example/c/app
Breakpoint 3 at 0xb7f665f8: file get.cpp, line 11.
Pending breakpoint "set" resolved
Breakpoint 1, main (argc=1, argv=0xbfArrayArray0504) at pk.cpp:7
7 int a = 100;
(gdb) n /* 繼續執行程序的下一行代碼 */
8 int b = get ();
(gdb) n /* 程序執行到了我們斷點所在的動態鏈接庫了 */
get x=0
Array int c = set (a);
(gdb) n
Breakpoint 3, set (a=100) at get.cpp:11
11 printf ("set a=%d\n", a);
(gdb) list /* 查看當前代碼行周圍的代碼,證明我們已經跟蹤到動態鏈接庫的源代碼裡面了 */
6 printf ("get x=%d\n", x);
7 return x;
8 }
Array int set (int a)
10 {
11 printf ("set a=%d\n", a);
12 x = a;
13 return x;
14 }
(gdb) n
set a=100
12 x = a;
(gdb) n
13 return x;
(gdb) n
14 }
(gdb) n
main (argc=1, argv=0xbfArrayArray0504) at pk.cpp:10
10 int d = get ();
(gdb) n
get x=100
11 printf ("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d);
(gdb) n
a=100,b=0,c=100,d=100
12 return 0;
(gdb) c
Continuing.
Program exited normally.
(gdb) quit /* 程序順利執行結束 */
如果我們沒有把動態鏈接庫放到指定目錄,比如/lib裡面,調試就會失敗,過程如下:
引用:
# gdb ./app
GNU gdb 6.4-debian
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show ing" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) b main
Breakpoint 1 at 0x804853c: file pk.cpp, line 7.
(gdb) b set
Function "set" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 2 (set) pending.
(gdb) run /* 雖然調試操作都一樣,但程序執行失敗 */
Starting program: /data/example/c/app
/data/example/c/app: error while loading shared libraries: libggg.so: cannot open shared object file: No such file or directory
Program exited with code 0177.
(gdb) quit
㈣ gdb調試問題
提示什麼, 如果是同一個文件,一個能調試,另一個不能調試,最大的原因是許可權問題, 這個你用GDB載入的時候,按R 運行後,一般會有提示的。 另外也可能文件損壞了。。你最好再 編譯一下,如果是直接 attach進行的調試,則極有可能是許可權問題。
㈤ 使用GNU/gdb調試Linux C/C++可執行程序查看出錯源代碼、設置斷點
gdb是GNU開源組織發布的一個強大的Linux程序調試工具,比圖形化的調試工具更強大,主要來調試C/C++語言程序。
Debug 版本的可執行程序包含調試信息,用於程序員調試程序。
Release 版本的可執行程序往往是進行了各種優化,使得程序在代碼大小和運行速度上都是最優的,以方便用戶使用。
用gcc/g++編譯時,要加上-g選項生成debug版本的可執行程序,否則就無法使用gdb調試了。
r 表示開始run, 如果在運行的過程中發生了錯誤,比如segmentation fault,可以查看此時的出錯源代碼:
通過b或者break設置斷點,斷點的設置可以通過函數名、行號、文件名+函數名、文件名+行號以及偏移量、地址等進行設置。
比如在function Peer_auto_save上設置斷點,在peer.c的第136行設置斷點:
從斷點處繼續運行
退出gdb
㈥ gdb載入動態庫成功,但是不能顯示動態庫中的源碼(gdb+gdbserver)
因為具體的給的不夠詳細,不清楚你遇到的情況。
如果僅從斷點上看,應該就是CApartment.cpp:55
但是,如果你的程序編譯的時候,不是-O0,那個可能回不到源碼,只能看匯編。
1、有時候(很少)就是編譯器的錯誤。
2、還有可能就是你調試的程序和你的源碼不匹配
3、你的程序已經崩潰了,破壞了堆棧或者GDB需要的數據。
4、這個地方有特殊的定位信息
5、其他情況,還是比較多的,經常遇到。
如果懂匯編,最好看看匯編。
如果不懂,看看那一條語句是最後一條能夠跟蹤的語句。
仔細看看最後一條語句的所有變數,應該能猜出來是什麼問題。