not*_*esh 3 c++ debugging multithreading gdb
我想在只有当堆栈通过特定函数时抛出异常时才使用GDB.
我的用例是我有一个Thread类,其doRun()函数在一个新线程中被调用.该线程捕获任何冒泡的异常,但我希望能够在抛出异常(未捕获)时中断.
我知道GDB可以做"反向调试"(很棒的概念)所以这可能会被使用,但是我想要一些更通用的东西 - 事实上,我希望这个解决方案找到我的.gdbinit文件.
最新版本的gdb有一些对此有用的便利函数,例如"$ _any_caller_matches".这些是用Python编写的,所以即使你的gdb没有内置它们,你也许可以获取代码并将其放入你的gdb中.
你可以使用它(未经测试,但你明白了):
catch throw if $_any_caller_matches("Thread::doRun")
Run Code Online (Sandbox Code Playgroud)
它没有出现$caller_matches(或其姐妹函数$caller_is)包含在GDB的基本安装中.
继续将源代码添加到GDB python函数文件夹中.
这个文件夹通常在/usr/share/gdb/python/gdb/function; 文件名应该是caller_is.py.
请注意,在使用时$caller_matches,底层实现正在使用re.match,因此请确保传递它的字符串适用于该函数.
同样,两个函数都有一个可选的第二个参数,默认为1,它指定了遍历堆栈(看起来)的距离.这意味着如果省略它,它将只检查当前函数的直接调用者.如果您想检查堆栈特定位置(也就是说,如果你要检查的祖父母主叫方),使用2,3等等.
我在下面列出了来源.
# 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()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
668 次 |
| 最近记录: |