2015-09-02 14 views
5

Come si possono vedere i valori di un pacchetto di parametri in una funzione variad in gdb?Visualizzazione dei valori dei pacchetti di parametri in gdb

codice di esempio (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); 
} 

Compila con

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

ed eseguire 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 

Come si può vedere: Dà solo il valore per a non per r ts.

EDIT: gdb: 7,9, g ++: 4.9.2 su MSYS2

EDIT: ubuntu 15.04 (g ++: 4.9.2, gdb: 7.9, binutils: 2,25) commette stesso risultato

EDIT: --debugging objdump ha comportato:

<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 

sembra che gli argomenti sono qui (ultimi due DW_TAG_fo rmal_parameter) ma senza i loro rispettivi nomi!

MODIFICA: la compilazione con -c ed eseguendo objdump sul file .o generato dà anche lo stesso risultato. Quindi vuol dire che è il mio g ++ che sta facendo questo sbagliato? (Mi piacerebbe non compilarlo da solo :-))

risposta

3

Un trucco che funziona sempre in gdb è premendo il tasto mentre si espandono i vars!

Quindi, se si digita:

gdb> stampa ts scheda

si ottiene

ts#0 ts#1

modo per stampare la variabile è sufficiente andare con :

gdb> print 'ts # 1'

importante utilizzare le virgolette singole qui!

anche

gdb> info args

dammi:

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

versione gdb è: 7.9.1, compilatore è 5.2.0

Come richiesto:

Ho compilato anche con gcb 4.7.2 precedenti e gdb obsoleto 7.7. Stessi risultati per me, funziona anche come spiegato qui!

EDIT: Per sapere a quale parte (compilatore vs. gdb) il problema è legato, si può provare a leggere le informazioni di debug manualmente:

Nota: ho cambiato il mio nome della funzione di 'FindItEasy' e parms a 'First/Rest' in modo che non posso cercare 2 lettere qui :-)

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> 

Forse puoi provare a trovare le informazioni di debug sul tuo file.

Suggerimento: la versione gdb e gcc non è completa. Entrambi gli strumenti si accumulano in cima ai binutils. E se i binutils sono obsoleti, è possibile che alcune informazioni di debug (come il formato nano) siano incomplete). Forse puoi controllare per quello!

+0

(Vedi la mia modifica per le versioni dei miei strumenti): Quindi sembra che questo sia nuovo a gdb 7.9.1 o che g ++ 4.9.2 non esporti i simboli necessari :-( – mmmmmmmm

+0

Così MSYS2 fa la differenza qui Non riuscivo a crederci ... ci proverò su Linux – mmmmmmmm

+0

Ho aggiunto alcuni suggerimenti per trovare il motivo del diverso comportamento: – Klaus