0

gdb在 linux 上运行 GNU grep 并单步执行它。大约 12 步后,控制权转移到setlocale.c没有可用源代码的 。

示例会话,在step 12没有可用的源代码信息并且list命令仅显示文件之后。

有没有办法gdb继续前进,直到带有源代码的文件再次可用。或者,有没有办法告诉 gdb 继续前进,直到控制权转移到另一个文件?

示例会话,显示最初可用的源代码,然后不可用setlocale.c

(gdb) start
Temporary breakpoint 1 at 0x402e50: file grep.c, line 2415.
Starting program: ~/ws/opt/grep/out/bin/grep --context=20 -r --line-number --byte-offset --include=\*.c int .
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Temporary breakpoint 1, main (argc=0x8, argv=0x7fffffffdaa8) at grep.c:2415
2415    {
(gdb) l
2410      return result;
2411    }
2412    
2413    int
2414    main (int argc, char **argv)
2415    {
2416      char *keys = NULL;
2417      size_t keycc = 0, oldcc, keyalloc = 0;
2418      int matcher = -1;
2419      bool with_filenames = false;
(gdb) s 12
__GI_setlocale (category=category@entry=0x6, locale=locale@entry=0x420b7b "") at setlocale.c:220
220 setlocale.c: No such file or directory.
(gdb) l
215 in setlocale.c
4

2 回答 2

0

你需要 gdbfinish命令。使用此命令,您可以退出没有可用源代码的当前堆栈帧。您可以根据需要多次使用它,直到您再次进入带有源代码的堆栈框架。请参阅文档

于 2018-07-15T12:21:19.403 回答
0

我最终gdb使用 Python API 编写了一个简单的脚本来执行此操作。它将继续前进,直到控制权转移到下一个文件,无论这是否涉及添加新的堆栈帧或离开当前的堆栈帧。

脚本可以用source leave_this_file.py. 它定义了一个被调用的命令,该命令leave_this_file可以不带参数调用,也可以重复多次。

该脚本有点临时,最终解析 gdb 命令的结果,frame 0而不是使用gdb's 的适当 API 之一来检查帧。

MAX_STEPS = 10000


def get_file_name():
    """extract the file name for the bottommost frame"""
    # example string
    #0  main (argc=0x7, argv=0x7fffffffdaa8) at grep.c:2415
    # <source fragment>
    where_str = gdb.execute("frame 0", from_tty=False, to_string=True)
    # last word of first line is file:line
    file_line = where_str.splitlines()[0].split()[-1]
    filename, _, line = file_line.rpartition(":")
    # confirm that line number is an int, raise otherwise
    int(line)
    return filename


def step_out_of_file_once():
    orig_file_name = get_file_name()
    current_file_name = orig_file_name
    counter = 0
    for x in range(MAX_STEPS):
        gdb.execute("step", from_tty=False, to_string=True)
        counter += 1
        current_file_name = get_file_name()
        if orig_file_name != current_file_name:
            break
    print("%s: %30s, %s: %s" % ("new", current_file_name, "steps", counter))


class LeaveThisFile(gdb.Command):
    """step out of the current file"""

    def __init__(self):
        gdb.Command.__init__(
            self, "leave_this_file", gdb.COMMAND_DATA, gdb.COMPLETE_SYMBOL, True
        )

    def invoke(self, arg, from_tty):
        # interpret the arg as a number of times to execute the command
        # 1 by default
        if arg:
            arg = int(arg)
        else:
            arg = 1
        for x in range(arg):
            step_out_of_file_once()


LeaveThisFile()

GNU grep这是运行时的一些示例输出gdb

2415    {
(gdb) startQuit
(gdb) source leave_this_file.py 
(gdb) leave_this_file 15
new:                    setlocale.c, steps: 18
new:        pthread_rwlock_wrlock.c, steps: 8
new: ../sysdeps/unix/sysv/linux/x86/hle.h, steps: 3
new:        pthread_rwlock_wrlock.c, steps: 1
new:                    setlocale.c, steps: 7
new: ../sysdeps/x86_64/multiarch/../strcmp.S, steps: 1
new:                    setlocale.c, steps: 48
new:                       getenv.c, steps: 4
new:     ../sysdeps/x86_64/strlen.S, steps: 2
new:                       getenv.c, steps: 16
new: ../sysdeps/x86_64/multiarch/../strcmp.S, steps: 64
new:                       getenv.c, steps: 53
new:                    setlocale.c, steps: 16
new: ../sysdeps/x86_64/multiarch/../strchr.S, steps: 5
new:                    setlocale.c, steps: 23
于 2018-07-17T02:42:58.103 回答