1. 程式人生 > >【linux】Valgrind工具集詳解(六):使用Valgrind gdbserver和GDB除錯程式

【linux】Valgrind工具集詳解(六):使用Valgrind gdbserver和GDB除錯程式

一、概述

在Valgrind下執行的程式不是由CPU直接執行的。相反,它執行在Valgrind提供的合成CPU上。這就是偵錯程式在Valgrind上執行時無法除錯程式的原因。

二、快速入門

在使用Memcheck工具時使用GDB除錯程式,啟動方式如下:
1、valgrind --vgdb = yes --vgdb-error = 0 可執程式
2、在另一個shell中,啟動GDB:gdb 可執程式
3、將以下命令提供給GDB:(gdb) target remote | vgdb
現在可以除錯程式了,例如插入斷點然後使用GDB continue 命令。

三、遠端除錯gdbserver

1、gdbserver的原理

本地除錯:GNU GDB偵錯程式通常用於除錯在同一臺機器上執行的程序。在此模式下,GDB使用系統呼叫來控制和查詢正在除錯的程式。

遠端除錯:GDB還可以除錯在不同計算機上執行的程序。為此,GDB定義了一個協議(即一組查詢和回覆資料包),它有助於獲取記憶體或暫存器的值,設定斷點等.gdbserver是這種“GDB遠端除錯”協議的實現。要除錯在遠端計算機上執行的程序,必須在遠端計算機端執行gdbserver

2、Valgrind中的gdbserver

Valgrind核心提供了一個內建的gdbserver實現,它使用–vgdb=yes 或–vgdb=full來啟用。此gdbserver允許在Valgrind的合成CPU上執行的程序遠端除錯。GDB將協議查詢資料包(例如“獲取暫存器內容”)傳送到Valgrind中的gdbserver。gdbserver執行查詢(例如,它將獲取合成CPU的暫存器值)並將結果返回給GDB。

GDB可以使用各種通道(TCP / IP,序列線等)與gdbserver進行通訊。在Valgrind中gdbserver的情況下,通過管道和一個名為vgdb的小幫助程式來完成通訊,該程式充當中介。如果沒有使用GDB,則vgdb也可用於從shell命令列向Valgrind gdbserver傳送監視命令。

3、遠端除錯步驟

3.1 在目標機上啟動gdbserver:
valgrind --tool = memcheck --vgdb = yes --vgdb-error = 0 ./prog
引數解釋:
–vgdb=yes:啟動gdbserver;
–vgdb-error = 0:在出現0個錯誤就開始除錯,一般用在插入斷點除錯中

3.2 在除錯機上啟動GDB及vgdb
(vgdb是GDB和valgrind中gdbserver的通訊的中間人)

gdb prog
(gdb) target remote | vgdb

如果遠端只有一個gdbserver列印資訊如下

Remote debugging using | vgdb
relaying data between gdb and process 2418
Reading symbols from /lib/ld-linux.so.2...done.
Reading symbols from /usr/lib/debug/lib/ld-2.11.2.so.debug...done.
Loaded symbols for /lib/ld-linux.so.2
[Switching to Thread 2418]
0x001f2850 in _start () from /lib/ld-linux.so.2
(gdb) 

如果有多個gdbserver,需要只當程序號PID
target remote | vgdb --pid=PID

(gdb) target remote | vgdb
Remote debugging using | vgdb
no --pid= arg given and multiple valgrind pids found:
use --pid=2479 for valgrind --tool=memcheck --vgdb=yes --vgdb-error=0 ./prog 
use --pid=2481 for valgrind --tool=memcheck --vgdb=yes --vgdb-error=0 ./prog 
use --pid=2483 for valgrind --vgdb=yes --vgdb-error=0 ./another_prog 
Remote communication error: Resource temporarily unavailable.

(gdb)  target remote | vgdb --pid=2479
Remote debugging using | vgdb --pid=2479
relaying data between gdb and process 2479
Reading symbols from /lib/ld-linux.so.2...done.
Reading symbols from /usr/lib/debug/lib/ld-2.11.2.so.debug...done.
Loaded symbols for /lib/ld-linux.so.2
[Switching to Thread 2479]
0x001f2850 in _start () from /lib/ld-linux.so.2
(gdb)