显示gdb中的参数包值 [英] Showing values of parameters packs in gdb

查看:135
本文介绍了显示gdb中的参数包值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在gdb中的可变函数中查看参数包的值?



示例代码(VariadicDebug.cpp):

  template< typename ... Ts> int Do(int a,Ts ... ts)
{
//这里添加断点。 a可以看到使用'打印a'但如何显示ts ???
return a;
}

int main(int argc,char ** argv)
{
return Do(0,Hello world!,88.9);
}

编译

  g ++ --std = c ++ 11 -O0 -g VariadicDebug.cpp 

并运行gdb:

  $ gdb ./a.exe 
GNU gdb
版权所有(C)2015 Free Software Foundation,Inc.
许可GPLv3 +:GNU GPL第3版或更高版本< http://gnu.org/licenses/gpl.html>
这是免费软件:您可以自由更改和重新分配。
在法律允许的范围内,没有任何保证。有关详细信息,请键入显示复制
和显示保修。
此GDB配置为x86_64-pc-msys。
键入show configuration以获取配置详细信息。
有关错误报告说明,请参阅:
< http://www.gnu.org/software/gdb/bugs/>
在线查找GDB手册和其他文档资源,网址为:
< http://www.gnu.org/software/gdb/documentation/>
要获得帮助,请键入help。
键入apropos word以搜索与word相关的命令...
从./a.exe...done读取符号。
(gdb)break VariadicDebug.cpp:4
断点1在0x100401760:文件VariadicDebug.cpp,第4行。
(gdb)run
启动程序:/ c / Data /测试/ a.exe
[新主题8008.0x1dd0]
[新主题8008.0x2898]
[新主题8008.0x26f0]
[新主题8008.0x1498]

断点1,Do< char const *,double> (a = 0)在VariadicDebug.cpp:4
4 return a;
(gdb)info args
a = 0

只为 不提供 的值。



编辑:在MSYS2上的gdb:7.9,g ++:4.9.2



EDIT :ubuntu 15.04 g:7.9.2,gdb:7.9,binutils:2.25)给出相同的结果



EDIT :objdump - p>

 < 1>< 81> ;:简写数:7(DW_TAG_subprogram)
& DW_AT_external:1
< 82> DW_AT_name:(indirect string,offset:0x0):FindItEasy< char const *,double>
< 86> DW_AT_decl_file:1
< 87> DW_AT_decl_line:1
< 88> DW_AT_linkage_name:(间接字符串,偏移量:0x3a):_Z10FindItEasyIIPKcdEEiiDpT_
< 8c> DW_AT_type:< 0x67>
< 90> DW_AT_low_pc:0x400529
< 98> DW_AT_high_pc:0x15
< a0> DW_AT_frame_base:1字节块:9c(DW_OP_call_frame_cfa)
< a2> DW_AT_GNU_all_call_sites:1
< a2> DW_AT_sibling:< 0xdc>
< 2>< a6> ;:简写数:8(DW_TAG_GNU_template_parameter_pack)
& DW_AT_name:Ts
< aa> DW_AT_sibling:< 0xb9>
< 3>< ae> ;:简写数:9(DW_TAG_template_type_param)
< af> DW_AT_type:< 0xdc>
< 3>< b3> ;:简写数:9(DW_TAG_template_type_param)
< b4> DW_AT_type:< 0xe7>
< 3>< b8> ;:简写数:0
< b9> ;:简写数:3(DW_TAG_formal_parameter)
& DW_AT_name:(间接字符串,偏移量:0x20):first
< be> DW_AT_decl_file:1
< bf> DW_AT_decl_line:1
< c0> DW_AT_type:< 0x67>
< c4> DW_AT_location:2字节块:91 6c(DW_OP_fbreg:-20)
2 c7:缩写号:10(DW_TAG_GNU_formal_parameter_pack)
c8 DW_AT_decl_file:1
< c9> DW_AT_decl_line:1
< 3>< ca> ;:简写编号:11(DW_TAG_formal_parameter)
< cb& DW_AT_type:< 0xdc>
< cf> DW_AT_location:2字节块:91 60(DW_OP_fbreg:-32)
3 d2:缩写号:11(DW_TAG_formal_parameter)
DW_AT_type:< 0xe7>
< d7> DW_AT_location:2字节块:91 58(DW_OP_fbreg:-40)
< da> ;:简写数:0
2< db> ;:简写数:0

似乎参数在这里(最后两个 DW_TAG_formal_parameter 名称!



EDIT :使用-c编译并在生成的.o文件上运行objdump也会提供相同的输出。这是什么意思是这是我的g ++,这是做错了吗? (我会感谢它不自己编译:-))

解决方案

同时扩展vars!



所以如果你键入:


gdb> print ts


您将获得



ts#0
ts#1



要打印您的变量,只需使用:


gdb> print'ts#1'




此处使用单引号重要!



此外



< >

gdb> info args


给我:



a = 0
ts#0 = 0x400d06Hello world!
ts#1 = 88,900000000000006



gdb版本是:7.9.1,编译器是5.2.0

根据要求:



我用旧的4.9.2 gcc编译aslo并运行过时的gdb 7.7。对我来说也是一样的结果,它的工作也如这里解释!



编辑:
要找出哪个方面(编译器对gdb)您可以尝试手动读出调试信息:



注意:我将我的函数名称更改为FindItEasy,并解析为First / Rest,以便我可以搜索不是2个字母: - )


objdump --debugging




 < 158> DW_AT_name:(间接字符串,偏移量:0x18d):FindItEasy 
< 15c> DW_AT_decl_file:1
< 15d> DW_AT_decl_line:14
< 15e> DW_AT_prototyped:1
< 15e> DW_AT_low_pc:0x400b6f
< 166> DW_AT_high_pc:0x37
< 16e> DW_AT_frame_base:1字节块:9c(DW_OP_call_frame_cfa)
< 170> DW_AT_GNU_all_call_sites:1
< 170> DW_AT_sibling:< 0x1f8>
< 2>< 174> ;:简写数:7(DW_TAG_formal_parameter)
& DW_AT_name:(间接字符串,偏移量:0x59):first
< 179> DW_AT_decl_file:1
< 17a> DW_AT_decl_line:14
< 17b> DW_AT_type:< 0x34>
< 17f> DW_AT_location:0xbe(位置列表)
2< 183> ;:简写数:7(DW_TAG_formal_parameter)
& DW_AT_name:(间接字符串,偏移量:0x66):rest#0
< 188> DW_AT_decl_file:1
< 189> DW_AT_decl_line:14
< 18a> DW_AT_type:< 0x6c>
< 18e> DW_AT_location:0x10a(位置列表)
2< 192> ;:简写数:7(DW_TAG_formal_parameter)
& DW_AT_name:(间接字符串,偏移量:0x6d):rest#1
< 197> DW_AT_decl_file:1
< 198> DW_AT_decl_line:14
< 199> DW_AT_type:< 0x2d>
< 19d> DW_AT_location:0x169(位置列表)
2< 1a1> ;:缩写号:8(DW_TAG_GNU_call_site)
& DW_AT_low_pc:0x400b89
< 1aa> DW_AT_abstract_origin:< 0x408>
< 1ae> DW_AT_sibling:< 0x1ba>

您可以尝试在文件中查找调试信息。



提示:拥有gdb和gcc版本不是完全的事实。两个工具都建立在binutils之上。如果binutils过时,可能有一些调试信息(如dwarf格式)不完整)。也许你可以检查一下!


How can one see the values of a parameter pack in a variadic function in gdb?

Sample code (VariadicDebug.cpp):

template <typename... Ts> int Do(int a, Ts... ts)
{
  // Add breakpoint here. a can be seen using 'print a' but how to show ts???
  return a;
}

int main(int argc, char **argv)
{
  return Do(0, "Hello world!", 88.9);
}

Compile with

g++ --std=c++11 -O0 -g VariadicDebug.cpp

And run gdb:

$ gdb ./a.exe
GNU gdb (GDB) 7.9
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-pc-msys".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.exe...done.
(gdb) break VariadicDebug.cpp:4
Breakpoint 1 at 0x100401760: file VariadicDebug.cpp, line 4.
(gdb) run
Starting program: /c/Data/tests/a.exe
[New Thread 8008.0x1dd0]
[New Thread 8008.0x2898]
[New Thread 8008.0x26f0]
[New Thread 8008.0x1498]

Breakpoint 1, Do<char const*, double> (a=0) at VariadicDebug.cpp:4
4         return a;
(gdb) info args
a = 0

As you can see: It only gives the value for a not for ts.

EDIT: gdb: 7.9, g++: 4.9.2 on MSYS2

EDIT: ubuntu 15.04 (g++: 4.9.2, gdb: 7.9, binutils: 2.25) gives same result

EDIT: objdump --debugging resulted in:

 <1><81>: Abbrev Number: 7 (DW_TAG_subprogram)
    <82>   DW_AT_external    : 1
    <82>   DW_AT_name        : (indirect string, offset: 0x0): FindItEasy<char const*, double>
    <86>   DW_AT_decl_file   : 1
    <87>   DW_AT_decl_line   : 1
    <88>   DW_AT_linkage_name: (indirect string, offset: 0x3a): _Z10FindItEasyIIPKcdEEiiDpT_
    <8c>   DW_AT_type        : <0x67>
    <90>   DW_AT_low_pc      : 0x400529
    <98>   DW_AT_high_pc     : 0x15
    <a0>   DW_AT_frame_base  : 1 byte block: 9c         (DW_OP_call_frame_cfa)
    <a2>   DW_AT_GNU_all_call_sites: 1
    <a2>   DW_AT_sibling     : <0xdc>
 <2><a6>: Abbrev Number: 8 (DW_TAG_GNU_template_parameter_pack)
    <a7>   DW_AT_name        : Ts
    <aa>   DW_AT_sibling     : <0xb9>
 <3><ae>: Abbrev Number: 9 (DW_TAG_template_type_param)
    <af>   DW_AT_type        : <0xdc>
 <3><b3>: Abbrev Number: 9 (DW_TAG_template_type_param)
    <b4>   DW_AT_type        : <0xe7>
 <3><b8>: Abbrev Number: 0
 <2><b9>: Abbrev Number: 3 (DW_TAG_formal_parameter)
    <ba>   DW_AT_name        : (indirect string, offset: 0x20): first
    <be>   DW_AT_decl_file   : 1
    <bf>   DW_AT_decl_line   : 1
    <c0>   DW_AT_type        : <0x67>
    <c4>   DW_AT_location    : 2 byte block: 91 6c      (DW_OP_fbreg: -20)
 <2><c7>: Abbrev Number: 10 (DW_TAG_GNU_formal_parameter_pack)
    <c8>   DW_AT_decl_file   : 1
    <c9>   DW_AT_decl_line   : 1
 <3><ca>: Abbrev Number: 11 (DW_TAG_formal_parameter)
    <cb>   DW_AT_type        : <0xdc>
    <cf>   DW_AT_location    : 2 byte block: 91 60      (DW_OP_fbreg: -32)
 <3><d2>: Abbrev Number: 11 (DW_TAG_formal_parameter)
    <d3>   DW_AT_type        : <0xe7>
    <d7>   DW_AT_location    : 2 byte block: 91 58      (DW_OP_fbreg: -40)
 <3><da>: Abbrev Number: 0
 <2><db>: Abbrev Number: 0

Seems that the arguments are in here (last two DW_TAG_formal_parameter) but without their respective names!

EDIT: Compiling with -c and running objdump on the generated .o file also gives the same output. So does this mean it's my g++ that is doing this wrong? (I would appreciate it to not compile it by myself :-) )

解决方案

A trick that always works in gdb is pressing tab while expanding vars!

So if you type:

gdb > print ts tab

you get

ts#0 ts#1

so to print your variable you simply go with:

gdb > print 'ts#1'

Important to use the single quotes here!

Also

gdb > info args

give me:

a=0 ts#0 = 0x400d06 "Hello world!" ts#1 = 88,900000000000006

gdb version is: 7.9.1, compiler is 5.2.0

As requested:

I compiled aslo with older 4.9.2 gcc and run outdated gdb 7.7. Same results for me, it works also as explained here!

EDIT: To find out to which side ( compiler vs. gdb ) the problem is related, you can try to read out the debug information manually:

Remark: I changed my function name to 'FindItEasy' and parms to 'First/Rest' so that I can search not for 2 letters here :-)

objdump --debugging

    <158>   DW_AT_name        : (indirect string, offset: 0x18d): FindItEasy
    <15c>   DW_AT_decl_file   : 1
    <15d>   DW_AT_decl_line   : 14
    <15e>   DW_AT_prototyped  : 1
    <15e>   DW_AT_low_pc      : 0x400b6f
    <166>   DW_AT_high_pc     : 0x37
    <16e>   DW_AT_frame_base  : 1 byte block: 9c    (DW_OP_call_frame_cfa)
    <170>   DW_AT_GNU_all_call_sites: 1
    <170>   DW_AT_sibling     : <0x1f8>
 <2><174>: Abbrev Number: 7 (DW_TAG_formal_parameter)
    <175>   DW_AT_name        : (indirect string, offset: 0x59): first
    <179>   DW_AT_decl_file   : 1
    <17a>   DW_AT_decl_line   : 14
    <17b>   DW_AT_type        : <0x34>
    <17f>   DW_AT_location    : 0xbe (location list)
 <2><183>: Abbrev Number: 7 (DW_TAG_formal_parameter)
    <184>   DW_AT_name        : (indirect string, offset: 0x66): rest#0
    <188>   DW_AT_decl_file   : 1
    <189>   DW_AT_decl_line   : 14
    <18a>   DW_AT_type        : <0x6c>
    <18e>   DW_AT_location    : 0x10a (location list)
 <2><192>: Abbrev Number: 7 (DW_TAG_formal_parameter)
    <193>   DW_AT_name        : (indirect string, offset: 0x6d): rest#1
    <197>   DW_AT_decl_file   : 1
    <198>   DW_AT_decl_line   : 14
    <199>   DW_AT_type        : <0x2d>
    <19d>   DW_AT_location    : 0x169 (location list)
 <2><1a1>: Abbrev Number: 8 (DW_TAG_GNU_call_site)
    <1a2>   DW_AT_low_pc      : 0x400b89
    <1aa>   DW_AT_abstract_origin: <0x408>
    <1ae>   DW_AT_sibling     : <0x1ba>

You maybe can try to find the debug informations on your file.

Hint: Having the gdb and gcc version is not the complete truth. Both tools build up on top of binutils. And if binutils are outdated, it is possible that some debug infos ( like dwarf format ) are incomplete ). Maybe You can check out for that!

这篇关于显示gdb中的参数包值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆