]> Git Repo - binutils.git/blob - gdb/testsuite/gdb.gdb/python-helper.exp
Automatic date update in version.in
[binutils.git] / gdb / testsuite / gdb.gdb / python-helper.exp
1 # Copyright 2021-2022 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 # This test exercises the gdb-gdb.py helper script that is generated
17 # into the GDB build directory.  This script is intended for use by
18 # developers to make debugging GDB easier.
19
20 load_lib selftest-support.exp
21
22 if [target_info exists gdb,noinferiorio] {
23     verbose "Skipping because of no inferiorio capabilities."
24     return
25 }
26
27 standard_testfile .cc
28
29 if { [build_executable "failed to build" $testfile $srcfile {debug c++}] } {
30     return -1
31 }
32
33 # Find the helper script in the GDB build directory.
34 set py_helper_script [file dirname $GDB]/gdb-gdb.py
35 if { ![file readable $py_helper_script] \
36          || [file type $py_helper_script] != "file" } {
37     untested "failed to find gdb-gdb.py helper script"
38     return
39 }
40
41 # Start GDB and check that we have python support.
42 gdb_start
43 if { [skip_python_tests] } {
44     untested "skipped gdb-gdb.py tests due to lack of python support"
45     return
46 }
47 gdb_exit
48
49 # The main test.  This is called by the self-test framework once GDB
50 # has been started on a copy of itself.
51 proc test_python_helper {} {
52     global py_helper_script decimal hex gdb_prompt bkptno_numopt_re
53     global inferior_spawn_id
54
55     # Source the python helper script.  This script registers the
56     # pretty printer for the object file called 'gdb', however, in our
57     # selftests we rename 'gdb' to 'xgdb', so the pretty printer
58     # doesn't get registered by default.
59     #
60     # So, after sourcing the script we do our own objfile scan and
61     # register the pretty printer for the objfile called 'xgdb'.
62     gdb_test_no_output "source $py_helper_script" \
63         "source gdb-gdb.py helper script"
64     gdb_test [multi_line_input \
65                   "python" \
66                   "for objfile in gdb.objfiles():" \
67                   "  if os.path.basename(objfile.filename) == \"xgdb\":" \
68                   "    objfile.pretty_printers.append(type_lookup_function)" \
69                   "end"] ".*" \
70         "register the type pretty printer"
71
72     # Now place breakpoints somewhere useful.  These locations can be
73     # any function that:
74     #
75     # (a) is easy to reach by issuing a simple gdb command, and
76     # (b) is unlikely to be modified very often within gdb, and
77     # (c) has a parameter that is either a 'struct type *' or a 'struct value *'.
78     gdb_breakpoint value_print qualified
79     gdb_breakpoint c_print_type qualified
80
81     # Disable all breakpoints until after we have loaded the test
82     # binary into the inner GDB.
83     gdb_test_no_output "disable breakpoints"
84
85     set outer_prompt_re "\\(outer-gdb\\) $"
86
87     # Adjust the prompt on the outer gdb, this just makes things a
88     # little clearer when trying to unpick which GDB is active.
89     gdb_test_no_output -prompt $outer_prompt_re  "set prompt (outer-gdb) " "set outer gdb prompt"
90
91     # Send a command to the outer GDB to continue the inner GDB.  The
92     # stop is being detected from the inner GDB, hence the use of -i
93     # here.
94     gdb_test_multiple "continue" "start inner gdb" {
95         -i "$inferior_spawn_id"
96         -re "\r\n$gdb_prompt $" {
97             pass $gdb_test_name
98         }
99     }
100
101     # Load the test executable into the inner GDB.  The output here is
102     # being read from the inner GDB, hence the use of -i here.
103     send_inferior "file -readnow $::binfile\n"
104     gdb_test_multiple "" "loading test binary into inner GDB" {
105         -i "$inferior_spawn_id"
106         -re "Reading symbols from.*\r\n$gdb_prompt $" {
107             pass $gdb_test_name
108         }
109     }
110
111     # Send Ctrl-C to the inner GDB, this should kick us back to the
112     # prompt of the outer GDB.
113     send_inferior "\003"
114     gdb_test -prompt $outer_prompt_re "" "" "interrupted the inner"
115
116     # Now enable all breakpoints within the outer GDB.
117     gdb_test_no_output -prompt $outer_prompt_re "enable breakpoints"
118
119     # We need to resume the inner GDB after interrupting it, this is
120     # done by sending 'continue'.  However, GDB will not redisplay the
121     # prompt in this case, so we have nothing that we can detect in
122     # order to know this continue was successful.  Still, if this
123     # didn't work, then later tests should fail.
124     send_gdb "continue\n"
125
126     # Control is back with the inner GDB.  Send a command to the inner
127     # GDB, this should result in the outer GDB stopping at one of the
128     # breakpoints we created..
129     send_inferior "print 1\n"
130     gdb_test -prompt $outer_prompt_re "" "Breakpoint $decimal, value_print.*" "hit breakpoint in outer gdb"
131
132     # Now inspect the type of parameter VAL, this should trigger the
133     # pretty printers.
134     set answer [multi_line \
135                     "${decimal} = " \
136                     "{pointer_type = 0x0," \
137                     " reference_type = 0x0," \
138                     " chain = 0x0," \
139                     " instance_flags = 0," \
140                     " length = $decimal," \
141                     " main_type = $hex}"]
142     gdb_test -prompt $outer_prompt_re "print *val->type" $answer "pretty print type"
143
144     set answer [multi_line \
145                     "$decimal = " \
146                     "{name = $hex \"int\"," \
147                     " code = TYPE_CODE_INT," \
148                     " flags = \[^\r\n\]+," \
149                     " owner = $hex \\(gdbarch\\)," \
150                     " target_type = 0x0," \
151                     " type_specific_field = TYPE_SPECIFIC_NONE}"]
152     gdb_test -prompt $outer_prompt_re "print *val->type->main_type" $answer "pretty print type->main_type"
153
154     # Send the continue to the outer GDB, which resumes the inner GDB,
155     # we then detect the prompt from the inner GDB, hence the use of
156     # -i here.
157     gdb_test_multiple "continue" "resume inner gdb" {
158         -i $inferior_spawn_id
159         -re "\r\n$gdb_prompt $" {
160             pass $gdb_test_name
161         }
162     }
163
164     # Now print an integer that was created from the DWARF
165     # information, this will include the TYPE_SPECIFIC_INT
166     # information.
167     send_inferior "print global_c.m_val\n"
168     gdb_test -prompt $outer_prompt_re "" "Breakpoint $decimal, value_print.*" "print integer from DWARF info"
169         
170     set answer [multi_line \
171                     "$decimal = " \
172                     "{name = $hex \"int\"," \
173                     " code = TYPE_CODE_INT," \
174                     " flags = \[^\r\n\]+," \
175                     " owner = $hex \\(objfile\\)," \
176                     " target_type = 0x0," \
177                     " int_stuff = { bit_size = $decimal, bit_offset = $decimal }}"]
178     gdb_test -prompt $outer_prompt_re "print *val->type->main_type" $answer "pretty print type->main_type for DWARF type"
179
180     # Send the continue to the outer GDB, which resumes the inner GDB,
181     # we then detect the prompt from the inner GDB, hence the use of
182     # -i here.
183     gdb_test_multiple "continue" "resume inner gdb again" {
184         -i $inferior_spawn_id
185         -re "\r\n$gdb_prompt $" {
186             pass $gdb_test_name
187         }
188     }
189
190     # Send a command to the inner GDB, this should result in the outer
191     # GDB stopping at the value_print breakpoint again.
192     send_inferior "ptype global_c\n"
193     gdb_test -prompt $outer_prompt_re "" "Breakpoint $bkptno_numopt_re, c_print_type.*" "hit breakpoint in outer gdb again"
194
195     set answer [multi_line \
196                     "$decimal = " \
197                     "{name = $hex \"CC\"," \
198                     " code = TYPE_CODE_STRUCT," \
199                     " flags = \[^\r\n\]+," \
200                     " owner = $hex \\(objfile\\)," \
201                     " target_type = 0x0," \
202                     " flds_bnds\\.fields\\\[0\\\]:" \
203                     "  {m_name = $hex \"m_val\"," \
204                     "   m_type = $hex," \
205                     "   m_loc_kind = FIELD_LOC_KIND_BITPOS," \
206                     "   bitsize = 0," \
207                     "   bitpos = 0}," \
208                     " cplus_stuff = $hex}"]
209     gdb_test -prompt $outer_prompt_re "print *type->main_type" $answer
210
211     return 0
212 }
213
214 # Use the self-test framework to run the test.
215 do_self_tests captured_main test_python_helper
This page took 0.037628 seconds and 4 git commands to generate.