作者KaryuuIssen (一闪)
看板C_and_CPP
标题[问题] gdb 印出 auto 成员函式回传值
时间Sat Oct 17 11:20:30 2020
开发平台(Platform): (Ex: Win10, Linux, ...)
Linux
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
GCC
问题(Question):
最近除错时发现 gdb 好像无法解析 auto 的类别成员函式回传值
一律只会印出 void
而且有确定该函式没被优化掉
程式码(Code):(请善用置底文网页, 记得排版,禁止使用图档)
简单例子如下:
#include <cstdio>
struct S {
auto f1(int v) { return v; }
int f2(int v) { return v; }
};
auto f3(int v) { return v; }
int main() {
S s;
printf("%d %d %d\n", s.f1(1), s.f2(1), f3(1)); // 1 1 1
}
使用 gdb 印出如下:
(gdb) p s.f1(1)
$1 = void
(gdb) p s.f2(1)
$2 = 1
(gdb) p f3(1)
$3 = 1
从结果看来一般函式 f3() 用 auto 回传就没这个问题
有人知道原因吗?
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.112.30.51 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1602904834.A.69F.html
2F:→ ucrxzero: 版本多少 ? 10/17 12:15
3F:→ KaryuuIssen: GDB 7.7.1 跟SO上这个好像是不同问题 10/17 12:26
4F:嘘 ucrxzero: 感觉要用很脏的写法印出来 10/17 13:21
5F:→ ucrxzero: 按错等补推 10/17 13:21
7F:→ ucrxzero: 1.0 10/17 13:25
这串我也有爬到 但没任何实质解答XD
8F:推 ucrxzero: 可以用-O0编吗 最不会有问题? 10/17 13:35
跟优化应该无关 至少我看有无 auto 生出来的程式段组语是一样的
10F:→ ucrxzero: 这是gdb evaluate function的过程 10/17 13:38
11F:→ ucrxzero: 我大胆猜测问题在create new stack那边 10/17 13:38
12F:→ ucrxzero: 毕竟全域不在stack里面 10/17 13:38
13F:推 ucrxzero: 所以全域的没问题 10/17 13:44
一开始跟你想的一样是 gdb 的问题
但刚刚我突然想到
看了一下 f1() 和 f3() 的 .debug_info 段发现:
f1()
------------------------------------------------------------------------------
<2><672>: Abbrev Number: 26 (DW_TAG_subprogram)
<673> DW_AT_external : 1
<673> DW_AT_name :
f1
<676> DW_AT_decl_file : 1
<677> DW_AT_decl_line : 19
<678> DW_AT_linkage_name: (indirect string, offset: 0x249): _ZN1S2f1Ei
<67c> DW_AT_type : <
0x6b1>
<680> DW_AT_declaration : 1
<680> DW_AT_object_pointer: <0x688>
<684> DW_AT_sibling : <0x693>
...
<1><
6b1>: Abbrev Number: 29 (
DW_TAG_unspecified_type)
<6b2> DW_AT_name : (indirect string, offset: 0x106):
auto
f3()
------------------------------------------------------------------------------
<1><
5e>: Abbrev Number: 4 (
DW_TAG_base_type)
<5f> DW_AT_byte_size : 4
<60> DW_AT_encoding : 5 (signed)
<61> DW_AT_name :
int
...
<1><735>: Abbrev Number: 34 (DW_TAG_subprogram)
<736> DW_AT_external : 1
<736> DW_AT_name :
f3
<739> DW_AT_decl_file : 1
<73a> DW_AT_decl_line : 24
<73b> DW_AT_linkage_name: (indirect string, offset: 0xf9): _Z2f3i
<73f> DW_AT_type : <
0x5e>
<743> DW_AT_low_pc : 0x400536
<74b> DW_AT_high_pc : 0xc
<753> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<755> DW_AT_GNU_all_call_sites: 1
<755> DW_AT_sibling : <0x766>
我把重点上色了 同样都是 auto
f1() 却无从推导出是回传 int?
看来是 DWARF 生成的问题? 所以 gdb 无法解读只能回传 void 吗
不知道有没有理解正确
14F:推 ucrxzero: 好想知道为什麽喔 10/17 15:33
15F:推 ucrxzero: 用print S::f1 却可以有int 10/17 16:21
16F:推 ucrxzero: 我今天有空帮你研究一下 10/17 16:25
17F:推 ucrxzero: 我用template却可以s.f1(123)=123 10/17 16:45
刚试了一下 S::f1 确实能出现 int ...
template 如果不行的话这个问题应该早就很多人讨论了XD
毕竟 auto 回传型别在 C++14 才支援
18F:推 ucrxzero: 11就有罗 10/17 17:23
19F:推 ucrxzero: 只是要配合decltype 10/17 17:26
20F:推 a1u1usul3: 随手试了一下,clang9编出来跑gdb是有推论出来的 10/19 17:05
21F:推 a1u1usul3: clang9编出来debug info直接就填int罗 10/19 17:19
22F:推 ucrxzero: 乾 10/19 18:08
23F:→ ucrxzero: 打错 10/19 18:08
感谢 刚试了一下 clang 真的OK了
看来就是 gcc 的 DWARF 生成的问题...
本来想说要去回报 gcc bug 的
发现原来几年前已经有人回报过 只是迟迟未处理:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78329
直到半年前又有相同的回报:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94459
这次就有处理了 已经修掉的样子
之後新版的 gcc 应该就不会有问题了
24F:推 ucrxzero: 跟我想的一样 10/20 10:20
25F:推 ucrxzero: 旧的版本可以试试看把回传值改成volatile试试 10/20 11:27
26F:→ ucrxzero: 刚刚想到的 10/20 11:27
一样不行 添加 CV 看来只是多一层绕道而已
auto 终究未解析出来
27F:推 ucrxzero: 抱歉 10/20 15:18
干嘛道歉XD 还要感谢你一直推帮我高调
※ 编辑: KaryuuIssen (140.112.30.51 台湾), 10/21/2020 05:28:55