1. 程式人生 > >linux下的除錯工具gdb

linux下的除錯工具gdb

在說這個問題之前,我們先弄清楚兩個概念:

1>什麼是Debug版本

2>什麼是Release版本

DebugRelease是兩種編譯方式,Debug通常稱為除錯版本,它包含除錯資訊,並且不做任何優化,便於程式設計師除錯程式

Release稱為釋出版本,它往往進行了各種優化,使得程式在程式碼大小和執行速度都是最優的,以便使用者很好的使用

我們都知道在linux下寫的程式碼不能直接進行除錯,必須將其變成可除錯的debug版本之後才能進行除錯

linux下有一個除錯工具gdb:

windows下是ide除錯工具

那麼我們接下來就說一說一些除錯命令(linux下)

1>首先是進入debug版本:

gcc -o exe *.c -g

2>如果要從主函式開始除錯:

gdb main

3>顯示主函式所在原始碼

4>b + 行號:在哪一行加斷點

5>顯示斷點:info b

6>執行:r

7>下一步:n(顯示變數)

8>s:直接進入將要被呼叫的函式裡面執行

9>p 變數名(或者display 變數名):顯示變數

10>顯示變數型別

11>顯示變數地址: p &變數名(陣列就是p 陣列名)

12>list *.c:1:從頭顯示(再加斷點)

13>直接給函式加斷點:b 函式名

14>結束:finish,跳出除錯:q

15>檢視執行緒:



16>thread 切換除錯的執行緒為指定ID的執行緒。(這裡就不舉例了)

下面這些來自網路摘抄:分享給大家:

break file.c:100 thread all 在file.c檔案第100行處為所有經過這裡的執行緒設定斷點。
set scheduler-locking off|on|step
這個是問得最多的。在使用step或者continue命令除錯當前被除錯執行緒的時候,其他執行緒也是同時執行的,怎麼只讓被除錯程式執行呢?通過這個命令就可以實現這個需求。
off 不鎖定任何執行緒,也就是所有執行緒都執行,這是預設值。
on 只有當前被除錯程式會執行。
step 在單步的時候,除了next過一個函式的情況(熟悉情況的人可能知道,這其實是一個設定斷點然後continue的行為)以外,只有當前執行緒會執行。
thread apply ID1 ID2 command 讓一個或者多個執行緒執行GDB命令command。
thread apply all command 讓所有被除錯執行緒執行GDB命令command。

gdb對於多執行緒程式的除錯有如下的支援:

執行緒產生通知:在產生新的執行緒時, gdb會給出提示資訊
(gdb) r
Starting program: /root/thread
[New Thread 1073951360 (LWP 12900)]
[New Thread 1082342592 (LWP 12907)]—以下三個為新產生的執行緒
[New Thread 1090731072 (LWP 12908)]
[New Thread 1099119552 (LWP 12909)]

檢視執行緒:使用info threads可以檢視執行的執行緒。
(gdb) info threads
4 Thread 1099119552 (LWP 12940) 0xffffe002 in ?? ()
3 Thread 1090731072 (LWP 12939) 0xffffe002 in ?? ()
2 Thread 1082342592 (LWP 12938) 0xffffe002 in ?? ()
* 1 Thread 1073951360 (LWP 12931) main (argc=1, argv=0xbfffda04) at thread.c:21
(gdb)

注意,行首的藍色文字為gdb分配的執行緒號,對執行緒進行切換時,使用該該號碼,而不是上文標出的綠色數字。
另外,行首的紅色星號標識了當前活動的執行緒

切換執行緒:使用 thread THREADNUMBER 進行切換,THREADNUMBER 為上文提到的執行緒號。下例顯示將活動執行緒從 1 切換至 4。
(gdb) info threads
4 Thread 1099119552 (LWP 12940) 0xffffe002 in ?? ()
3 Thread 1090731072 (LWP 12939) 0xffffe002 in ?? ()
2 Thread 1082342592 (LWP 12938) 0xffffe002 in ?? ()
* 1 Thread 1073951360 (LWP 12931) main (argc=1, argv=0xbfffda04) at thread.c:21
(gdb) thread 4
[Switching to thread 4 (Thread 1099119552 (LWP 12940))]#0 0xffffe002 in ?? ()
(gdb) info threads
* 4 Thread 1099119552 (LWP 12940) 0xffffe002 in ?? ()
3 Thread 1090731072 (LWP 12939) 0xffffe002 in ?? ()
2 Thread 1082342592 (LWP 12938) 0xffffe002 in ?? ()
1 Thread 1073951360 (LWP 12931) main (argc=1, argv=0xbfffda04) at thread.c:21
(gdb)
後面就是直接在你的執行緒函式裡面設定斷點,然後continue到那個斷點,一般情況下多執行緒的時候,由於是同時執行的,最好設定 set scheduler-locking on這樣的話,只調試當前執行緒

17>linux 下除錯core 的命令,察看堆疊狀態命令

配置coredump

2.1 使用除錯版本

一般地,在軟體開發階段,都會使用除錯版本。亦即程式使用-g來編譯,另外要注意,不能用strip命令對生成的可執行檔案進行精簡。這一切均是為了可執行檔案保留著除錯資訊,以方便使用gdb進行呼叫。

2.2 設定ulimit

為了在程式崩潰時產生coredump檔案,要設定coredump大小。先進行檢視:

[email protected]:~# ulimit -a
time(seconds)        unlimited
file(blocks)         unlimited
data(kb)             unlimited
stack(kb)            8192
coredump(blocks)     0
memory(kb)           unlimited
locked memory(kb)    64
process              545
nofiles              1024
vmemory(kb)          unlimited
locks                unlimited

可以看到,其中coredump一行值為0,此時無法產生coredump檔案。因此要設定其檔案為無限大,命令:


# ulimit -c unlimited

結果如下:

[email protected]:~# ulimit -a

time(seconds)        unlimited
file(blocks)         unlimited
data(kb)             unlimited
stack(kb)            8192
coredump(blocks)     unlimited
memory(kb)           unlimited
locked memory(kb)    64
process              545
nofiles              1024
vmemory(kb)          unlimited
locks                unlimited

另外,要程式執行的同一環境下執行。比如,不能在一個終端設定ulimit,而在另一個終端執行程式,這樣不能生成coredump檔案的。

為了保證coredump檔名稱的唯一性,可以用下面命令設定:
# echo 'core.%e.%s.%t' > /proc/sys/kernel/core_pattern  # 設定生成的coredump檔名稱

2.3 萬一程式因段錯誤等原因崩潰,則會生成core檔案。

2.4 3、有了coredump檔案,就可以結合可執行檔案,使用gdb進行除錯了,命令形式如下:
# gdb hello core

下面使用李遲當年參考uboot原始碼實現的命令列解析程式碼為例。 首先,程式碼編譯時必須帶-g選項。

然後,在命令列中設定core檔案:
[[email protected] creadline]$ ulimit -c unlimited

執行程式:
[[email protected] creadline]$ ./a.out
Hit any key to stop autoboot:  0
You abort.
NotAShell> print
in print ...
Segmentation fault (core dumped)     

(已經產生了coredump檔案)


下面使用gdb除錯:
[[email protected] creadline]$ gdb a.out core.2896

gdb列印資訊如下:
GNU gdb Fedora (6.8-29.fc10)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...


warning: Can't read pathname for load map: Input/output error.
Reading symbols from /usr/lib/libstdc++.so.6...done.
Loaded symbols for /usr/lib/libstdc++.so.6
Reading symbols from /lib/libm.so.6...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libgcc_s.so.1...done.
Loaded symbols for /lib/libgcc_s.so.1
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
[New process 2896]
#0  0x0084d626 in memcpy () from /lib/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.9-2.i686 libgcc-4.3.2-7.i386 libstdc++-4.3.2-7.i386
(gdb)

使用bt命令檢視函式呼叫的棧幀(用where命令也可以):
(gdb) bt
#0  0x0084d626 in memcpy () from /lib/libc.so.6
#1  0x08048660 in ?? ()
#2  0x08049f5d in do_print (argc=1, argv=0xbf8935dc) at my_command.c:31
#3  0x08048cc2 in run_command (cmd=0x804cca0 "print") at command.c:380
#4  0x08049e93 in readline_test ()
#5  0x08049ee6 in main ()
(gdb)
 可以看到最後出現的可疑的程式碼函式為do_print,裡面使用到了memcpy,具體是哪裡,可以用frame NUM檢視棧幀。比如,檢視第2個棧幀:
(gdb) frame 2
#2  0x08049f5d in do_print (argc=1, argv=0xbf8935dc) at my_command.c:31
31          memcpy(p, buffer, 5);
(gdb) 

可以看到,已經輸出了檔名稱、行號、函式等重要資訊。
至此,就可以根據資訊修改程式碼了。

下面給出錯誤函式程式碼片段:
int do_print(int argc, char * const argv[])
{
    printf("in print ...\n");
    char* p = NULL;
    char* buffer = "hello";
    memcpy(p, buffer, 5);     //  注:拷貝到空指標,錯誤!!!
    return 0;
}



相關推薦

arm linux交叉編譯gdb除錯工具

       由於嵌入式系統資源有限性,一般不能直接在目標系統上進行除錯,通常採gdb+gdbserver的方式進行除錯。Gdbserver在目標系統中執行,gdb則在宿主機上執行。要進行GDB除錯,目標系統必須包括gdbserver程式,宿主機也必須安裝gdb程式,一般li

linux除錯工具gdb

在說這個問題之前,我們先弄清楚兩個概念: 1>什麼是Debug版本 2>什麼是Release版本 Debug和Release是兩種編譯方式,Debug通常稱為除錯版本,它包含除錯資訊,並且不做任何優化,便於程式設計師除錯程式 Release稱為釋出版本,它往往進

Linux除錯段錯誤的方法[Segmentation Fault]--GDB

4. 段錯誤的除錯方法 4.1 使用printf輸出資訊 這個是看似最簡單但往往很多情況下十分有效的除錯方式,也許可以說是程式設計師用的最多的除錯方式。簡單來說,就是在程式的重要程式碼附近加上像printf這類輸出資訊,這樣可以跟蹤並打印出段錯誤在程式碼中可能出現的位置。為了方便使用這種方法,可以使用

linux除錯工具gdb用法

1 .編譯選項 1.1  gcc -g ソースコード名 「-g」オプションを付けてビルドを行うことで、「gdb」でデバッグ可能となります。 デバッグの為の情報が増えますので生成された実行ファイルのサイ

linux如何使用gdb除錯

gdb是linux下非常好用的一個除錯工具,雖然它是命令列模式的除錯工具,但是它的功能強大到你無法想象,這裡簡單介紹下gdb下常用的命令。首先編譯生成可執行檔案(這裡的test.c是一個簡單的求前n項和的程式)。gcc -g test.c -o test(-g選項告訴gcc在編譯程式時加入除錯資訊)。接下來可

GDBLinux除錯程式

引言:GDB是GUN釋出的一款功能強大的程式除錯工具。 * GDB主要完成下面三個方面的功能:  1、啟動被除錯的程式; 2、指定程式在某個位置暫停; 3、當程式暫停時,可以檢查程式的狀態(包括變數值等)。 * GDB使用方法: 1、編譯生成的可執行檔案: gcc

Linux同步工具inotify+rsync使用詳解

server linux 通道 主機 Linux下同步工具inotify+rsync使用詳解 Posted on 2014-12-12 | In Linux | 9 | Visitors 4381. rsync1.1 什麽是rsyncrsync是一個遠程數據同步工具,可通過LAN/WAN

linuxDOS工具

site 使用 說明 -s 壓力 inux and linux下 tcp/ip 1.Hping3/Nping   TCP/IP數據包生成工具,用於壓力測試,安全審計 2.使用hping進行DOS攻擊 命令:hping3 -c 10000 -d 120 -S -w 64

Linux應急工具

rac reserve mar req contact system cal kthread smi Linux下的應急工具 在Linux下,應急的查看點無非那個幾個,一是看表現(宕機、高CPU、高內存、高IO、高網絡通信),二看連接、三看進程、四看日誌、五看文件(Lin

kail linux nc工具的基本使用(安全牛視頻)

效果 設計 思路 all 可靠 加密方法 了解 一個 網站 一、簡介 nc是netcat的簡寫,有著網絡界的瑞士×××美譽。因為它短小精悍、功能實用,被設計為一個簡單、可靠的網絡工具。 nc 常用的命令有兩個: 1、-v 輸出詳細的交互或者出錯信息 2、-n 如果後面是ip

Linux實用工具

音訊錄製:Audacity 串列埠除錯:cutecom HTTP_post/get:Postman 磁碟管理工具:gparted linux下第三方庫: jsoncpp(json解析)/*json.h和原始檔不能在用以目錄,原因未知*/ opencv(影象處理/只用到拍照)

linuxxclock工具沒有安裝的處理

我們在輸入xclock時,報找不到命令: [[email protected]dbserver ~]$ xclock -bash: xclock: command not found   如果排除了路徑找不到的問題,那麼,一般是

詳解Linuxauto工具製作Makefile原始碼包(製作篇)

收藏於 2012-03-25 遷移自個人的百度空間 -------------------------------- 一、 概述 為了更好的製作configure與Makefile,我先把製作流程給寫在這裡,好讓大夥都有個心理準備。這裡只說流程,不做解釋。(附圖供參考) 1

詳解Linuxauto工具製作Makefile原始碼包(工具安裝篇)

收藏於 2012-03-25 遷移自個人的百度空間 ------------------------------- 一、引子 咱們都知道make好用,但是大型的軟體make是很麻煩的,為了解決這個問題,先人們就發明了autoconf與automake工具,用這些工具可以非常方便的製作

linux 除錯coredump檔案

1、coredump簡介 在linux後臺開發過程中可能一不小心出現訪問非法記憶體而產生段錯誤,面對段錯誤我們有時候可以通過列印定位,但那樣比較慢,我們可以利用linux提供了一種方法,當程式奔潰時核心會儲存程式執行的堆疊資訊到一個coredump檔案,我們可以通過gdb除錯這個coredump

linux程式設計工具推薦和配置-vim

工欲善其事,必先利其器 從網上找的兩個比較強大的程式碼編輯和工程開發工具,沉下心來,好好配置一下,畢竟程式碼是陪伴程式設計師一生最長久的夥伴,值得好好打理一下。 為了方便大家下載使用,我把它

Linux開發工具備註

編輯器-Vim 都知道vim是Linux下的編輯器之神,當然還有emacs也是特別NB的,個人在Linux下比較常用的也就是Vim了,接下來說說vim的一些配置技巧: 配置常見的程式碼模板 func Setfilehead() call append(0

Linux 防毒工具 clamav

 clamav 防毒工具;Linux下的防毒工具; 下載地址; 最新 包 0.101 官網下載地址:http://www.clamav.net/downloads最新包地址: https://clamav-site.s3.amazonaws.com/production/release_f

MonjaDB—MongoDB ubuntu linux管理工具 客戶端管理工具 mongovue的替換者

MonjaDB 是一個 MongoDB 的 GUI 客戶端工具,提供直觀的 MongoDB 資料管理的功能,支援 Windows/Mac/Linux. MonjaDB 是一個 Eclipse 外掛,必須先安裝 Eclipse。 主要特點: 易用WYSIWYG 編輯 JSO

linuxPing工具的C語言實現

前言:     ping命令是用來檢視網路上另一個主機系統的網路連線是否正常的一個工具     ping命令的工作原理是:向網路上的另一個主機系統傳送ICMP報文,如果指定系統得到了報文,它將把報文一模一樣地傳回給傳送者 ping實現的九大步驟:       第一步:建立i