禁用优化后,GDB STL函数仍然显示为内联

gdb stl functions still show as inlined after disabling optimizations

本文关键字:显示 函数 STL 优化 GDB      更新时间:2023-10-16

我已经用python支持构建了gdb-7.12,并启用了漂亮的打印功能,并按照https://sourceware.org/gdb/wiki/STLSupport配置了我的gdbinit文件。

但是当我打印任何容器的大小时:

p ivec.size()
Cannot evaluate function -- may be inlined

这是我正在使用的MCVE

#include <vector>
using namespace std;
int main(){
  vector<int> ivec;
  return 0;
}

我已经尝试了不同的编译选项

g++-6 -g -O0 -fno-inline-functions -gdwarf-2 Source.cpp --std=c++14

事实上,我已经尝试了以上所有选项的组合,但总是遇到同样的问题。

我尝试切换到gdb-7.11(也从源代码构建),看看它是否解决了这个问题,也切换到g++-4.8,它们似乎都没有解决这个问题。

我做错了什么?是否有一些特定的顺序,你必须给出选项?

编辑:

很多人建议用一些宏来解决这个问题,但我的问题不是打印这些函数,我可以自己写一些漂亮的打印方法。

我的问题是为什么函数显示为内联即使禁用优化与- 0选项后?

我的问题是为什么函数显示为内联即使禁用优化与- 0选项后?

g++将只实例化你的程序实际使用的模板,而你的程序实际上并不使用size方法。

您可以使用nm:

检查此设置。
$ nm -C q|grep size
$

如果我改变你的程序使用return ivec.size(),那么我可以:

(gdb) p ivec.size()
$1 = 0

内联和非实例化的整个情况就是编写gdb xmethod支持的原因。而且,libstdc++有一些xmethods(尽管我没有检查它是否特别有这个)。

GDB错误消息Cannot evaluate function -- may be inlined有点误导,因为内联不是函数不可用的唯一原因。

在您的示例中,std::vector<T>::size() simple没有在编译时实例化(到std::vector<int>::size()),因为它没有被使用。

这取决于你的GDB漂亮的打印支持的版本,如果它可以绕过丢失的size()实例化当你输入p ivec.size()call ivec.size()(例如GDB 8.0.1在Fedora 27可以)。但是即使是旧版本的STL漂亮打印支持,你也可以通过打印向量本身来解决这个问题,例如:

(gdb) p ivec
$1 = std::vector of length 0, capacity 0

然而,你可以显式地确保size()被实例化,要么在你的程序中使用它,要么在一个翻译单元中显式地实例化int的完整模板类:

template class std::vector<int>;