作者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/m.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