GDB调试可执行文件
使用GDB调试可执行文件是后台开发的基础,需要熟练掌握,下面就通过一个简单例子说明如何使用GDB调试可执行文件以及如何在GDB调试可执行文件时输出STL容器的元素内容。
示例程序如下:
#include<iostream>
#include<vector>
#include<map>
using namespace std;
int fun()
{
int i=0;
return i;
}
int main()
{
fun();
vector<int> vec_int;
vec_int.push_back(1);
vec_int.push_back(2);
map<int, int> mapping;
mapping.insert(pair<int, int>(0, 1));
return 0;
}
编译生成可执行文件时使用命令gdb -g main.cpp -o main.o,调试该可执行文件时使用命令gdb main.o,使用下面不同的参数会得到不同的效果,如下:
l :列出代码
b 12 :在第12行设置breakpoint
r :开始运行程序
n :执行下一行代码
c :运行代码直至断点位置或者程序结束处
s :进入函数体内部继续调试
倘若需要看某个变量的值,可以通过print variable来读取variable的值,该方法对于STL容器的支持并不好,此处将如下代码拷入.gdbinit中:
#
# STL GDB evaluators/views/utilities - 1.03
#
# The new GDB commands:
# are entirely non instrumental
# do not depend on any "inline"(s) - e.g. size(), [], etc
# are extremely tolerant to debugger settings
#
# This file should be "included" in .gdbinit as following:
# source stl-views.gdb or just paste it into your .gdbinit file
#
# The following STL containers are currently supported:
#
# std::vector<T> -- via pvector command
# std::list<T> -- via plist or plist_member command
# std::map<T,T> -- via pmap or pmap_member command
# std::multimap<T,T> -- via pmap or pmap_member command
# std::set<T> -- via pset command
# std::multiset<T> -- via pset command
# std::deque<T> -- via pdequeue command
# std::stack<T> -- via pstack command
# std::queue<T> -- via pqueue command
# std::priority_queue<T> -- via ppqueue command
# std::bitset<n> -- via pbitset command
# std::string -- via pstring command
# std::widestring -- via pwstring command
#
# The end of this file contains (optional) C++ beautifiers
# Make sure your debugger supports $argc
#
# Simple GDB Macros writen by Dan Marinescu (H-PhD) - License GPL
# Inspired by intial work of Tom Malnar,
# Tony Novac (PhD) / Cornell / Stanford,
# Gilad Mishne (PhD) and Many Many Others.
# Contact: dan_c_marinescu@yahoo.com (Subject: STL)
#
# Modified to work with g++ 4.3 by Anders Elton
# Also added _member functions, that instead of printing the entire class in map, prints a member.
#
# std::vector<>
#
define pvector
if $argc == 0
help pvector
else
set $size = $arg0._M_impl._M_finish - $arg0._M_impl._M_start
set $capacity = $arg0._M_impl._M_end_of_storage - $arg0._M_impl._M_start
set $size_max = $size - 1
end
if $argc == 1
set $i = 0
while $i < $size
printf "elem[%u]: ", $i
p *($arg0._M_impl._M_start + $i)
set $i++
end
end
if $argc == 2
set $idx = $arg1
if $idx < 0 || $idx > $size_max
printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
else
printf "elem[%u]: ", $idx
p *($arg0._M_impl._M_start + $idx)
end
end
if $argc == 3
set $start_idx = $arg1
set $stop_idx = $arg2
if $start_idx > $stop_idx
set $tmp_idx = $start_idx
set $start_idx = $stop_idx
set $stop_idx = $tmp_idx
end
if $start_idx < 0 || $stop_idx < 0 || $start_idx > $size_max || $stop_idx > $size_max
printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
else
set $i = $start_idx
while $i <= $stop_idx
printf "elem[%u]: ", $i
p *($arg0._M_impl._M_start + $i)
set $i++
end
end
end
if $argc > 0
printf "Vector size = %u\n", $size
printf "Vector capacity = %u\n", $capacity
printf "Element "
whatis $arg0._M_impl._M_start
end
end
document pvector
Prints std::vector<T> information.
Syntax: pvector <vector> <idx1> <idx2>
Note: idx, idx1 and idx2 must be in acceptable range [0..<vector>.size()-1].
Examples:
pvector v - Prints vector content, size, capacity and T typedef
pvector v 0 - Prints element[idx] from vector
pvector v 1 2 - Prints elements in range [idx1..idx2] from vector
end
#
# std::list<>
#
define plist
if $argc == 0
help plist
else
set $head = &$arg0._M_impl._M_node
set $current = $arg0._M_impl._M_node._M_next
set $size = 0
while $current != $head
if $argc == 2
printf