当前位置:Linux教程 - Linux - GDB调试器使用手册(八)

GDB调试器使用手册(八)



         设置断点
    =============
    使用\"break\"或简写成\"b\"来设置断点。gdb使用环境变量$bpnum来记录你最新设置的
    断点。
    你有不少方法来设置断点。


    `break FUNCTION\"
    此命令用来在某个函数上设置断点。当你使用允许函数重载的语言比如C++时,有可
    能同时在几个重载的函数上设置了断点。

    `break +OFFSET\"
    `break -OFFSET\"
    在当前程序运行到的前几行或后几行设置断点。OFFSET为行号。

    `break LINENUM\"
    在行号为LINENUM的行上设置断点。程序在运行到此行之前停止。

    `break FILENAME:LINENUM\"
    在文件名为FILENAME的原文件的第LINENUM行设置断点。

    `break FILENAME:FUNCTION\"
    在文件名为FILENAME的原文件的名为FUNCTION的函数上设置断点。
    当你的多个文件中可能含有相同的函数名时必须给出文件名。

    `break *ADDRESS\"
    在地址ADDRESS上设置断点,这个命令允许你在没有调试信息的程
    序中设置断点。
    `break\"
    当\"break\"命令不包含任何参数时,\"break\"命令在当前执行到的程
    序运行栈中的下一条指令上设置一个断点。除了栈底以外,这个命令使
    程序在一旦从当前函数返回时停止。相似的命令是\"finish\",但\"finish\"
    并不设置断点。这一点在循环语句中很有用。
    gdb在恢复执行时,至少执行一条指令。

    `break ... if COND\"
    这个命令设置一个条件断点,条件由COND指定;在gdb每次执行到此
    断点时COND都被计算当COND的值为非零时,程序在断点处停止。这意味着
    COND的值为真时程序停止。...可以为下面所说的一些参量。

    `tbreak ARGS\"
    设置断点为只有效一次。ARGS的使用同\"break\"中的参量的使用。

    `hbreak ARGS\"
    设置一个由硬件支持的断点。ARGS同\"break\"命令,设置方法也和
    \"break\"相同。但这种断点需要由硬件支持,所以不是所有的系统上这个
    命令都有效。这个命令的主要目的是用于对EPROM/ROM程序的调试。因为
    这条命令可以在不改变代码的情况下设置断点。这可以同SPARCLite DSU
    一起使用。当程序访问某些变量和代码时,DSU将设置“陷井”。注意:
    你只能一次使用一个断点,在新设置断点时,先删除原断点。
    `thbreak ARGS\"
    设置只有一次作用的硬件支持断点。ARGS用法同\"hbreak\"命令。这个命令
    和\"tbreak\"命令相似,它所设置的断点只起一次作用,然后就被自动的删除。这
    个命令所设置的断点需要有硬件支持。

    `rbreak REGEX\"
    在所有满足表达式REGEX的函数上设置断点。这个命令在所有相匹配的函数
    上设置无条件断点,当这个命令完成时显示所有被设置的断点信息。这个命令设
    置的断点和\"break\"命令设置的没有什么不同。这样你可以象操作一般的断点一
    样对这个命令设置的断点进行删除,使能,使不能等操作。当调试C++程序时这
    个命令在重载函数上设置断点时非常有用。

    `info breakpoints [N]\"
    `info break [N]\"
    `info watchpoints [N]\"
    显示所有的断点和观察点的设置表,有下列一些列

    *Breakpoint Numbers*----断点号
    *Type*----断点类型(断点或是观察点)
    *Disposition*---显示断点的状态。

    *Enabled or Disabled*---使能或不使能。\"y\"表示使能,\"n\"表示不使能。

    *Address*----地址,断点在你程序中的地址(内存地址)
    *What*---地址,断点在你程序中的行号。
    如果断点是条件断点,此命令还显示断点所需要的条件。
    带参数N的\"info break\"命令只显示由N指定的断点的信息。
    此命令还显示断点的运行信息(被执行过几次),这个功能在使用\"ignore\"
    命令时很有用。你可以\"ignore\"一个断点许多次。使用这个命令可以查看断点
    被执行了多少次。这样可以更快的找到错误。
    gdb允许你在一个地方设置多个断点。但设置相同的断点无疑是弱智的。不过
    你可以使用条件断点,这样就非常有用。
    gdb有时会自动在你的程序中加入断点。这主要是gdb自己的需要。比如为了正
    确的处理C语言中的\"longjmp\"。这些内部断点都是负值,以\"-1\"开始。\"info
    breakpoints\"不会显示它们。
    不过你可以使用命令’maint info breakpoints\"来查看这些断点。

    `maint info breakpoints\"
    使用格式和\"info breakpoints\"相同,显示所有的断点,无论是你设置的还是
    gdb自动设置的。
    以下列的含义:

    `breakpoint\"
    断点,普通断点。
    `watchpoint\"
    普通观察点。

    `longjmp\"
    内部断点,用于处理\"longjmp\"调用。

    `longjmp resume\"
    内部断点,设置在\"longjmp\"调用的目标上。

    `until\"
    \"until\"命令所使用的内部断点。

    `finish\"
    \"finish\"命令所使用的内部断点。
    设置观察点
    ==============
    你可以使用观察点来停止一个程序,当某个表达式的值改变时,观察点会将程序
    停止。而不需要先指定在某个地方设置一个断点。
    由于观察点的这个特性,使观察点的使用时开销比较大,但在捕捉错误时非常有
    用。特别是你不知道你的程序什么地方出了问题时。

    `watch EXPR\"
    这个命令使用EXPR作为表达式设置一个观察点。GDB将把表达式加入到程序中
    并监视程序的运行,当表达式的值被改变时GDB就使程序停止。这个也可以被用在
    SPARClite DSU提供的新的自陷工具中。当程序存取某个地址或某条指令时(这个地
    址在调试寄存器中指定),DSU将产生自陷。对于数据地址DSU支持\"watch\"命令,然而
    硬件断点寄存器只能存储两个断点地址,而且断点的类型必须相同。就是两个
    \"rwatch\"型断点,或是两个\"awatch\"型断点。

    `rwatch EXPR\"
    设置一个观察点,当EXPR被程序读时,程序被暂停。

    `awatch EXPR\"
    设置一个观察点,当EXPR被读出然后被写入时程序被暂停。这个命令和\"awatch\"
    命令合用。

    `info watchpoints\"
    显示所设置的观察点的列表,和\"info break\"命令相似。
    *注意:*在多线程的程序中,观察点的作用很有限,GDB只能观察在一个线程中
    的表达式的值如果你确信表达式只被当前线程所存取,那么使用观察点才有效。GDB
    不能注意一个非当前线程对表达式值的改变。

    断点和异常
    ==============
    在一些语言中比如象GNU C++,实现了异常处理。你可以使用GDB来检查异常发生的
    原因。而且GDB还可以列出在某个点上异常处理的所有过程。

    `catch EXCEPTIONS\"
    你可以使用这个命令来在一个被激活的异常处理句柄中设置断点。EXCEPTIONS是
    一个你要抓住的异常。
    你一样可以使用\"info catch\"命令来列出活跃的异常处理句柄。
    现在GDB中对于异常处理由以下情况不能处理。
    * 如果你使用一个交互的函数,当函数运行结束时,GDB将象普通情况一样把控制返
    回给你。如果在调用中发生了异常,这个函数将继续运行直到遇到一个断点,一个信号
    或是退出运行。
    * 你不能手工产生一个异常( 即异常只能由程序运行中产生 )
    * 你不能手工设置一个异常处理句柄。
    有时\"catch\"命令不一定是调试异常处理的最好的方法。如果你需要知道异常产生的
    确切位置,最好在异常处理句柄被调用以前设置一个断点,这样你可以检查栈的内容。
    如果你在一个异常处理句柄上设置断点,那么你就不容易知道异常发生的位置和原因。
    要仅仅只在异常处理句柄被唤醒之前设置断点,你必须了解一些语言的实现细节。
    比如在GNU C++中异常被一个叫\"__raise_exception\"的库函数所调用。这个函数的原
    型是:

    /* ADDR is where the exception identifier is stored.
    ID is the exception identifier. */
    void __raise_exception (void **ADDR, void *ID);
    要使GDB在栈展开之前抓住所有的句柄,你可以在函数\"__raise_exception\"上设置断点。
    对于一个条件断点,由于它取决于ID的值,你可以在你程序中设置断点,当某个特
    别的异常被唤醒。当有一系列异常被唤醒时,你可以使用多重条件断点来停止你的程序。
    发布人:netbull 来自:中国LINUX开发联盟