从特定函数调用时,GDB会在抛出异常时中断

时间:2014-11-05 19:12:01

标签: c++ multithreading debugging gdb

我希望在堆栈通过特定函数时抛出异常时使用GDB中断。

我的用例是我有一个Thread类,其doRun()函数在新线程中调用。该线程捕获任何冒泡的异常,但我希望能够在抛出异常(未捕获)时中断。

我知道GDB可以做"反向调试" (很棒的概念)所以这可能会被使用,但我喜欢更通用的东西 - 事实上,我希望这个解决方案找到我的.gdbinit文件。

2 个答案:

答案 0 :(得分:6)

gdb的最新版本有一些对此有用的便利功能,例如" $ _ any_caller_matches"。这些是用Python编写的,所以即使你的gdb没有内置它们,你也许可以获取代码并将其放入你的gdb中。

你会喜欢它(未经测试,但你明白了):

catch throw if $_any_caller_matches("Thread::doRun")

答案 1 :(得分:5)

它不会出现$caller_matches(或其姐妹函数$caller_is)包含在GDB的基本安装中。


继续将source code添加到您的GDB python函数文件夹中。

此文件夹通常位于/usr/share/gdb/python/gdb/function;文件名应为caller_is.py

请注意,使用$caller_matches时,底层实现正在使用re.match,因此请确保您传递的字符串适用于该函数。

同样,两个函数都有一个可选的第二个参数,默认为1,它指定了遍历堆栈(看)的距离。这意味着如果省略它,它将只检查当前函数的直接调用者。如果要检查特定的堆栈位置(即,如果要检查祖父母调用者),请使用23等。

我已经在下面提供了来源。

# Caller-is functions.

# Copyright (C) 2008 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import gdb
import re

class CallerIs (gdb.Function):
    """Return True if the calling function's name is equal to a string.
This function takes one or two arguments.
The first argument is the name of a function; if the calling function's
name is equal to this argument, this function returns True.
The optional second argument tells this function how many stack frames
to traverse to find the calling function.  The default is 1."""

    def __init__ (self):
        super (CallerIs, self).__init__ ("caller_is")

    def invoke (self, name, nframes = 1):
        frame = gdb.selected_frame ()
        while nframes > 0:
            frame = frame.older ()
            nframes = nframes - 1
        return frame.name () == name.string ()

class CallerMatches (gdb.Function):
    """Return True if the calling function's name matches a string.
This function takes one or two arguments.
The first argument is a regular expression; if the calling function's
name is matched by this argument, this function returns True.
The optional second argument tells this function how many stack frames
to traverse to find the calling function.  The default is 1."""

    def __init__ (self):
        super (CallerMatches, self).__init__ ("caller_matches")

    def invoke (self, name, nframes = 1):
        frame = gdb.selected_frame ()
        while nframes > 0:
            frame = frame.older ()
            nframes = nframes - 1
        return re.match (name.string (), frame.name ()) is not None

CallerIs()
CallerMatches()