Подтвердить что ты не робот

GNU gdb не может входить в функции шаблонов (OS X Mavericks)

Я установил gdb 7.7 (из источников GNU) под OS X Mavericks (10.9.2). Я кодировал его, поэтому он отлично работает, когда я отлаживаю файл c++, который не содержит шаблонов. Однако он не может входить в функции шаблона (может входить в обычные функции, а просто не входить в шаблонные). Когда я набираю команду step в сеансе отладки, она просто выполняет над ней функцию, как если бы для функции шаблона отсутствовали символы отладки. Моя функция шаблона не является даже функцией-членом, это просто простая функция, определенная внутри main.cpp.

Я скомпилирую свою программу с помощью g++ -g -O0 main.cpp (я использую g++4.8.2 из macports, а не clang++), даже попробовал -fno-inline, все еще такое же поведение, не может входить в функции шаблона. Является ли это gdb известной проблемой под OS X Mavericks? Или может кто-нибудь воспроизвести ошибку?

мой код:

#include <iostream>

template <typename T> // template
void f(T x)
{
    std::cout << "In f:" << std::endl;
    std::cout << x << std::endl;
}

void g() // non-template
{
    std::cout << "It works here!" << std::endl;
    std::cout << "Exiting g()..." << std::endl;
}

int main() 
{
    f<double>(12.3); // gdb does not step into f()
    g(); // gdb steps into g()
}

Не удается выполнить шаг f после точки останова в f<double>(12.3). Если f() является регулярной функцией, такой как g() в моем коде, тогда она переходит в. Спасибо!

Обновление: gdb работает так же, как и в любой другой ОС, например linux/windows/solaris. Это проблема, связанная с OS X.

Reading symbols from a.out...done.
(gdb) disassemble main
Dump of assembler code for function main():
   0x0000000100000d62 <+0>: push   %rbp
   0x0000000100000d63 <+1>: mov    %rsp,%rbp
   0x0000000100000d66 <+4>: movabs $0x402899999999999a,%rax
   0x0000000100000d70 <+14>:    movq   %rax,%xmm0
   0x0000000100000d75 <+19>:    callq  0x100000e44
   0x0000000100000d7a <+24>:    callq  0x100000d0c <g()>
   0x0000000100000d7f <+29>:    mov    $0x0,%eax
   0x0000000100000d84 <+34>:    pop    %rbp
   0x0000000100000d85 <+35>:    retq
End of assembler dump.
(gdb)

Теперь мы устанавливаем точку останова при входе main()

(gdb) b main
Breakpoint 1 at 0x100000d66: file src/templated_bug.cpp, line 22.
(gdb) r
Starting program: /Users/vlad/template_gdb_bug/a.out

Breakpoint 1, main () at src/templated_bug.cpp:22
22      f<double>(12.3);
(gdb) s
In f:
12.3
23      g();
(gdb) s
g () at src/templated_bug.cpp:16
16      cout<<"It works here!"<<endl;
(gdb) s
It works here!
17      cout<<"Exiting g()..."<<endl;
(gdb) s
Exiting g()...
18  }
(gdb) s
main () at src/templated_bug.cpp:24
24  }
(gdb) s
[Inferior 1 (process 50945) exited normally]
(gdb)

Как вы можете видеть, он не входит внутрь f(), а выполняет шаги внутри g(). Кроме того,

(gdb) disassemble f
No symbol "f" in current context.

Однако для другой функции g(), которая не является шаблоном, символы загружаются, и я могу ее дизассемблировать.

(gdb) disassemble g
Dump of assembler code for function g():
   0x0000000100000d0c <+0>: push   %rbp
   0x0000000100000d0d <+1>: mov    %rsp,%rbp
   0x0000000100000d10 <+4>: lea    0x193(%rip),%rsi        # 0x100000eaa
   0x0000000100000d17 <+11>:    mov    0x2ea(%rip),%rax        # 0x100001008
   0x0000000100000d1e <+18>:    mov    %rax,%rdi
   0x0000000100000d21 <+21>:    callq  0x100000e5c
   0x0000000100000d26 <+26>:    mov    0x2e3(%rip),%rdx        # 0x100001010
   0x0000000100000d2d <+33>:    mov    %rdx,%rsi
   0x0000000100000d30 <+36>:    mov    %rax,%rdi
   0x0000000100000d33 <+39>:    callq  0x100000e4a
   0x0000000100000d38 <+44>:    lea    0x17a(%rip),%rsi        # 0x100000eb9
   0x0000000100000d3f <+51>:    mov    0x2c2(%rip),%rax        # 0x100001008
   0x0000000100000d46 <+58>:    mov    %rax,%rdi
   0x0000000100000d49 <+61>:    callq  0x100000e5c
   0x0000000100000d4e <+66>:    mov    0x2bb(%rip),%rdx        # 0x100001010
   0x0000000100000d55 <+73>:    mov    %rdx,%rsi
   0x0000000100000d58 <+76>:    mov    %rax,%rdi
   0x0000000100000d5b <+79>:    callq  0x100000e4a
   0x0000000100000d60 <+84>:    pop    %rbp
   0x0000000100000d61 <+85>:    retq
End of assembler dump.
4b9b3361

Ответ 1

Кажется, есть проблемы с командой на в порту MacOS gdb. В качестве обходного пути вы можете установить точку останова при запуске функции, чтобы перейти в функцию шаблона:

(gdb) b f<double>
Breakpoint 1 at 0x1000015ab: file ./gdb_tmpl.cpp, line 6.
(gdb) run
Starting program: /Users/vershov/tmp/tests/a.out 

Breakpoint 1, f<double> (x=12.300000000000001) at ./gdb_tmpl.cpp:6
6       std::cout << "In f:" << std::endl;

Кроме того, вы можете разобрать его, просто используйте правильную команду:

(gdb) disass f
No symbol "f" in current context.
(gdb) disass f<double>
Dump of assembler code for function f<double>(double):
   0x0000000100001590 <+0>: push   %rbp
   0x0000000100001591 <+1>: mov    %rsp,%rbp
   0x0000000100001594 <+4>: sub    $0x40,%rsp
   0x0000000100001598 <+8>: mov    0xa71(%rip),%rdi        # 0x100002010
   0x000000010000159f <+15>:    lea    0x9a0(%rip),%rsi        # 0x100001f46
...