小技巧:gdb退出时不显示提示信息

gdb在退出时会提示:

    A debugging session is active.
    Inferior 1 [process 19114 ] will be killed.
    Quit anyway? (y or n)

如果不想显示这个信息,则可以在gdb中使用“set confirm off”命令把提示信息关掉,也可以把这个命令加到.gdbinit文件里。

分享几篇关于gcc和gdb的文章

海法Linux俱乐部是一群在以色列海法地区生活的Linux工程师定期组织的,分享在Linux下开发程序经验的聚会。网站是http://www.haifux.org/。其中有很多topic,涉及的范围很广,感兴趣的同学可以登陆这个网站看一下。我把其中和gcc和gdb相关的文章选出来,分享在下面:
gdb – customize it the way you want
Advanced GDB
Compiling Effectively for Cell with GCC
GCC Profile Guided Optimization

GDB talk in FOSDEM 2014 (slides and video record)

Pedro gave a talk on FOSDEM 2014, named "GDB, so where are we now?
Status of GDB's ongoing target and run control projects".  The slides
can be found here
https://github.com/palves/FOSDEM-2014/blob/master/presentation.pdf
Video record is http://video.fosdem.org/2014/previews/fosdem/fosdem_2014/dv/K4201/2014-02-02/13_58_00.ogv

The PDF is very helpful to understand some confusing concepts for both users
and developers, such as all-stop, non-stop, async, and run all-stop on top of non-stop.

使用gdb pretty printer调试go dist

作者:xmj

1、GDB提供了Pretty Printer功能,可以在调试程序的时候,通过自定义的打印程序来更好的显示一个数据结构的值。

相关信息可以参考gdb手册:
23.2.2.7 Writing a Pretty-Printer
https://sourceware.org/gdb/current/onlinedocs/gdb/Writing-a-Pretty_002dPrinter.html#Writing-a-Pretty_002dPrinter

2、Go源码包里的dist目录,go/src/cmd/dist,是Go的bootstraping工具,用来自举go编译器,以及各种可以使用脚本来完成的杂活。其本身是用C写的,里面有两个常用的数据类型,定义在a.h里:

// A Buf is a byte buffer, like Go's []byte.
typedef struct Buf Buf;
struct Buf
{
        char *p;
        int len;
        int cap;
};

// A Vec is a string vector, like Go's []string.
typedef struct Vec Vec;
struct Vec
{
        char **p;
        int len;
        int cap;
};

我们在gdb中调试dist的时候,如果想查看一个Buf或者Vec的内容,如下:

(gdb) p b
$1 = {p = 0x80574b8, len = 0x3, cap = 0x40}
(gdb) p gccargs
$2 = {p = 0x8059778, len = 0x4, cap = 0x40}

显然,不是很令人满意。

3、为此,我们可以为其定义pretty printers。这里,需要两部分内容,首先创建一个目录,以及一个文件:python/printers.py,内容如下:

import gdb

class BufPrinter(object):
    "Print a struct Buf."

    def __init__ (self, val):
        self.val = val

    def to_string (self):
        p = self.val['p']
        l = self.val['len']
        ret = "\""
        ret += p.string(length = l)
        ret += "\""
        return ret

class VecPrinter(object):
    "Print a struct Vec."

    def __init__ (self, val):
        self.val = val

    def to_string (self):
        p = self.val['p']
        l = self.val['len']
        ret = "\""
        for i in range(l):
            if i > 0:
                ret += " "
            ret += p[i].string()
        ret += "\""
        return ret

def build_pretty_printer():
    pp = gdb.printing.RegexpCollectionPrettyPrinter("golang")
    pp.add_printer('Buf', '^Buf$', BufPrinter)
    pp.add_printer('Vec', '^Vec$', VecPrinter)
    return pp

def register_golang_printer():
    gdb.printing.register_pretty_printer(
        gdb.current_objfile(),
        build_pretty_printer())

然后,在~/.gdbinit里,增加如下代码:

python
import sys
sys.path.insert(0, '/path/to/your/python')
from printers import register_golang_printer
register_golang_printer ()
end

4、此时,再通过gdb调试dist,显示如下:

(gdb) p b
$1 = "gcc"
(gdb) p gccargs
$2 = "gcc -Wall -Wstrict-prototypes -Wextra"