Скажите GDB, чтобы пропустить стандартные файлы - PullRequest
11 голосов
/ 15 апреля 2011

Я отлаживаю код C ++ с помощью GDB, и когда он входит в конструктор некоторого объекта, содержащего объекты стандартной библиотеки, он показывает мне конструктор этих объектов (например, std::map) и всего, что находится под ним.

Я знаю об операторе next, но я бы предпочел в основном черный список любого стандартного библиотечного кода, который никогда не является источником исследуемой ошибки. Желаемое поведение заключается в том, что простой skip отправит меня к следующему коду "user-land".

Ответы [ 4 ]

11 голосов
/ 14 ноября 2012

* Изменения в GDB 7.4

  • GDB теперь позволяет пропускать неинтересные функции и файлы при переходе с помощью команд "пропустить функцию" и "пропустить файл".
7 голосов
/ 23 марта 2017

GDB 7.12 поддерживает глобализацию файлов, чтобы указать файлы, которые нужно пропустить в отладчике. Документация для того же - ниже:

https://sourceware.org/gdb/onlinedocs/gdb/Skipping-Over-Functions-and-Files.html

Чтобы пропустить вход во все заголовки библиотеки в каталоге / usr / include / c ++ / 5 / bits, добавьте следующие строки в ~ / .gdbinit

# To skip all .h files in /usr/include/c++/5/bits
skip -gfi /usr/include/c++/5/bits/*.h

Вместо того, чтобы пропустить определенный файл, скажем, stl_vector.h, добавьте следующие строки в ~ / .gdbinit

# To skip the file /usr/include/c++/5/bits/stl_vector.h
skip file /usr/include/c++/5/bits/stl_vector.h

Выполнение вышеизложенного с версией GDB 7.11 и ниже приводит к следующей ошибке:

Ignore function pending future shared library load? (y or [n]) [answered N; input not from terminal]

Однако GDB 7.12, похоже, решил вышеуказанную проблему.

Этот блог решает ту же проблему для GDB версии 7.11 или ниже.

Примечание - Вы можете использовать приведенную ниже команду из командной строки gdb, чтобы получить список всех файлов, отмеченных для пропуска

info skip
1 голос

Шаг инструкции и пропустить все файлы без источника

Это будет слишком медленно для большинства приложений, но это весело!

Основано на: Отображениекаждая инструкция по сборке выполняется в gdb

class ContinueUntilSource(gdb.Command):
    def __init__(self):
        super().__init__(
            'cus',
            gdb.COMMAND_BREAKPOINTS,
            gdb.COMPLETE_NONE,
            False
        )
    def invoke(self, argument, from_tty):
        argv = gdb.string_to_argv(argument)
        if argv:
            gdb.write('Does not take any arguments.\n')
        else:
            done = False
            thread = gdb.inferiors()[0].threads()[0]
            while True:
                message = gdb.execute('si', to_string=True)
                if not thread.is_valid():
                    break
                try:
                    path = gdb.selected_frame().find_sal().symtab.fullname()
                except:
                    pass
                else:
                    if os.path.exists(path):
                        break
ContinueUntilSource()

Протестировано в Ubuntu 16.04, GDB 7.11. GitHub upstream .

0 голосов
/ 09 марта 2018

Изменено из команды ответа Сиро Сантилли ss шаги внутри определенного источника.Вы можете указать имя исходного файла, или текущее будет добавлено.Очень удобно для перехода по источникам bison / yacc или другим мета-источникам, которые генерируют код С и вставляют директивы #line.

import os.path

class StepSource(gdb.Command):
    def __init__(self):
        super().__init__(
            'ss',
            gdb.COMMAND_BREAKPOINTS,
            gdb.COMPLETE_NONE,
            False
        )
    def invoke(self, argument, from_tty):
        argv = gdb.string_to_argv(argument)
        if argv:
            if len(argv) > 1:
                gdb.write('Usage:\nns [source-name]]\n')
                return
            source = argv[0]
            full_path = False if os.path.basename(source) == source else True
        else:
            source = gdb.selected_frame().find_sal().symtab.fullname()
            full_path = True
        thread = gdb.inferiors()[0].threads()[0]
        while True:
            message = gdb.execute('next', to_string=True)
            if not thread.is_valid():
                break
            try:
                cur_source = gdb.selected_frame().find_sal().symtab.fullname()
                if not full_path:
                    cur_source = os.path.basename(cur_source)
            except:
                break
            else:
                if source == cur_source:
                    break
StepSource()

Известные ошибки

  1. не прерываетсяотладчик на SIGINT во время работы;
  2. изменен pass на break при исключении, поскольку не уверен, что это правильно.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...