2015-09-02 12 views
5

Làm cách nào để xem giá trị của gói tham số trong hàm variadic trong gdb?Hiển thị giá trị của các gói tham số trong gdb

Mẫu mã (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 với

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

Và chạy 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 

Như bạn có thể thấy: Nó chỉ cung cấp giá trị cho a không cho r ts.

EDIT: gdb: 7,9, g ++: 4.9.2 trên MSYS2

EDIT: ubuntu 15.04 (g ++: 4.9.2, gdb: 7,9, binutils: 2.25) cho kết quả tương tự

EDIT: --debugging objdump dẫn:

<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 

vẻ như là đối số ở đây (cuối cùng hai DW_TAG_fo rmal_parameter) nhưng không có tên tương ứng của chúng!

EDIT: Biên dịch với -c và chạy objdump trên tệp .o được tạo cũng cung cấp cùng một đầu ra. Vì vậy, điều này có nghĩa là nó của tôi g + + đó là làm điều này sai? (Tôi sẽ đánh giá cao nó để không biên dịch nó bởi bản thân mình :-))

Trả lời

3

Một thủ thuật luôn luôn hoạt động trong gdb là nhấn tab trong khi mở rộng vars!

Vì vậy, nếu bạn gõ:

gdb> in ts tab

bạn nhận được

ts#0 ts#1

như vậy để in biến của bạn, bạn chỉ đơn giản là đi với :

gdb> print 'ts # 1'

quan trọng để sử dụng dấu nháy đơn ở đây!

Cũng

gdb> args thông tin

cho tôi:

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

phiên bản gdb là: 7.9.1, trình biên dịch là 5.2.0

Theo yêu cầu:

Tôi đã biên dịch aslo với cũ hơn 4.9.2 gcc và chạy gdb lỗi thời 7.7. Cùng một kết quả cho tôi, nó cũng hoạt động như được giải thích ở đây!

EDIT: Để tìm hiểu mà bên (biên dịch so với gdb) các vấn đề có liên quan, bạn có thể thử để đọc các thông tin gỡ lỗi bằng tay:

Ghi chú: Tôi đã thay đổi tên hàm của tôi để 'FindItEasy' và parms để 'Đầu tiên/Nghỉ ngơi' vì vậy mà tôi có thể tìm kiếm không cho 2 chữ cái ở đây :-)

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> 

Bạn có thể thử tìm thông tin gỡ rối trên tệp của mình.

Gợi ý: Việc có phiên bản gdb và gcc không phải là sự thật hoàn chỉnh. Cả hai công cụ xây dựng trên đầu trang của binutils. Và nếu binutils là lỗi thời, có thể là một số infos gỡ lỗi (như định dạng lùn) là không đầy đủ). Có lẽ bạn có thể kiểm tra cho điều đó!

+0

(Xem chỉnh sửa của tôi cho các phiên bản công cụ của tôi): Vì vậy, có vẻ như đây là mới đối với gdb 7.9.1 hoặc g ++ 4.9.2 không xuất các ký hiệu cần thiết :-( – mmmmmmmm

+0

Vì vậy, MSYS2 tạo sự khác biệt ở đây Tôi khó có thể tin được ... Tôi sẽ thử nó trên Linux – mmmmmmmm

+0

Tôi đã thêm một số gợi ý để tìm ra lý do cho các hành vi khác nhau – Klaus

Các vấn đề liên quan