Точки останова GDB не попадают в функции шаблона - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь установить точки останова в шаблонных функциях на C ++ через GDB. Я пробовал три возможных подхода.

  1. break fileName: functionName => работает для не шаблонных функций (укажите c для одной функции )
  2. rbreak fileName :. => точки останова для всех функций в данном файле, но, похоже, это не работает для шаблонных функций
  3. break fileName: lineNumber => работает как для не шаблонных, так и для шаблонных функций, но проблема здесь для меня в том, что у меня есть для изменения этого номера каждый раз.

Общая цель - я использую сценарий, как показано ниже, для отслеживания полного потока кода через GDB, но в моем коде также есть много шаблонных функций. Пример сценария GDB ниже

set logging on
b func2
commands
silent
bt 1
continue
end
b func1
commands
silent
bt 1
set logging off
continue
end
  • Один из вариантов - использовать rbreak filename :.
  • запустить код один раз, а
  • запустить код еще раз, не выходя из GDB. На этот раз он распознает функции и точки останова работают.

Не могли бы вы помочь предложить правильное решение или сообщить мне, если я чего-то упускаю? Любая помощь / предложение приветствуется и сильно упрощает мою отладку.

Заранее большое спасибо !!

1 Ответ

1 голос
/ 05 мая 2020

Проблема, скорее всего, в имени функции, которую вы используете при попытке установить точку останова в gdb.

Названия функций, которые использует gdb, не в исходном файле, а в двоичном. Шаблонные функции на самом деле не являются функциями. Это просто «рецепт», и когда вы фактически компилируете код с использованием шаблона, компилятор реализует для вас функцию, используя рецепт (по одной для каждой комбинации параметров шаблона, которые вы фактически использовали).

Рассмотрите код ниже

#include <iostream>

double tripleInput(double x) { return 3 * x; }

template <typename T>
inline T doubleInput(const T& x) {
    return 2 * x;
}


int main(int argc, char *argv[])
{
    std::cout << doubleInput(13) << std::endl;
    std::cout << doubleInput(1.72) << std::endl;

    std::cout << tripleInput(1.72) << std::endl;
    return 0;
}

Когда мы компилируем это и отлаживаем в gdb, gdb увидит три функции (помимо main): tripleInput, doubleInput<int> и doubleInput<double>. Если вы напишете в gdb break tripleInput, точка останова будет добавлена ​​в функцию tripleInput, но если вы напишете просто break doubleInput, gdb скажет, что функция не определена.

Вам нужно написать либо break doubleInput<int>, либо break doubleInput<double>, но обратите внимание, что добавление такой точки останова остановится только в этом c экземпляре шаблона. Это отличается от добавления точки останова к строке в шаблоне. В этом случае gdb фактически добавляет точку останова с несколькими местоположениями . Попробуйте info breakpoints после создания точки останова обоими методами, чтобы увидеть разницу.

Я не знаю, что можно сделать что-то вроде break doubleInput<*>, но, глядя в документацию, это не кажется


СОВЕТ: В разделе GDB TAB заполнит имена функций, включая экземпляры шаблонов.


Edit

Я полностью забыл о rbreak. Он может устанавливать точки останова для всех функций, соответствующих регулярному выражению. Это означает, что мы можем легко добавить точку останова во все экземпляры шаблона функции с

rbreak doubleInput*

или даже во все функции в файле с

rbreak main.cpp:.*
...