1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
|
# Copyright (C) 2009-2015 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This file is part of the GDB testsuite. It tests the mechanism
# of exposing types to Python.
load_lib gdb-python.exp
standard_testfile
if [get_compiler_info c++] {
return -1
}
# Build inferior to language specification.
proc build_inferior {exefile lang} {
global srcdir subdir srcfile testfile hex
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${exefile}" executable "debug $lang"] != "" } {
untested "Couldn't compile ${srcfile} in $lang mode"
return -1
}
return 0
}
# Restart GDB.
proc restart_gdb {exefile} {
global srcdir subdir srcfile testfile hex
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${exefile}
if ![runto_main ] then {
perror "couldn't run to breakpoint"
return
}
}
# Set breakpoint and run to that breakpoint.
proc runto_bp {bp} {
gdb_breakpoint [gdb_get_line_number $bp]
gdb_continue_to_breakpoint $bp
}
proc test_fields {lang} {
with_test_prefix "test_fields" {
global gdb_prompt
# .fields() of a typedef should still return the underlying field list
gdb_test "python print (len(gdb.parse_and_eval('ts').type.fields()))" "2" \
"$lang typedef field list"
if {$lang == "c++"} {
# Test usage with a class
gdb_py_test_silent_cmd "print (c)" "print value (c)" 1
gdb_py_test_silent_cmd "python c = gdb.history (0)" "get value (c) from history" 1
gdb_py_test_silent_cmd "python fields = c.type.fields()" "get fields from c.type" 1
gdb_test "python print (len(fields))" "2" "Check number of fields (c)"
gdb_test "python print (fields\[0\].name)" "c" "Check class field c name"
gdb_test "python print (fields\[1\].name)" "d" "Check class field d name"
gdb_test "python print (c.type == gdb.parse_and_eval('d').type)" "False"
gdb_test "python print (c.type == gdb.parse_and_eval('d').type.fields()\[0\].type)" \
"True"
# Test fields of a method (its parameters)
gdb_test "python print (len (gdb.parse_and_eval ('C::a_method').type.fields ()))" "3"
gdb_test "python print (gdb.parse_and_eval ('C::a_method').type.fields ()\[0\].type)" "C \\* const"
gdb_test "python print (gdb.parse_and_eval ('C::a_method').type.fields ()\[1\].type)" "int"
gdb_test "python print (gdb.parse_and_eval ('C::a_method').type.fields ()\[2\].type)" "char"
gdb_test "python print (len (gdb.parse_and_eval ('C::a_const_method').type.fields ()))" "3"
gdb_test "python print (gdb.parse_and_eval ('C::a_const_method').type.fields ()\[0\].type)" "const C \\* const"
gdb_test "python print (gdb.parse_and_eval ('C::a_const_method').type.fields ()\[1\].type)" "int"
gdb_test "python print (gdb.parse_and_eval ('C::a_const_method').type.fields ()\[2\].type)" "char"
gdb_test "python print (len (gdb.parse_and_eval ('C::a_static_method').type.fields ()))" "2"
gdb_test "python print (gdb.parse_and_eval ('C::a_static_method').type.fields ()\[0\].type)" "int"
gdb_test "python print (gdb.parse_and_eval ('C::a_static_method').type.fields ()\[1\].type)" "char"
}
# Test normal fields usage in structs.
gdb_py_test_silent_cmd "print (st)" "print value (st)" 1
gdb_py_test_silent_cmd "python st = gdb.history (0)" "get value (st) from history" 1
gdb_py_test_silent_cmd "python fields = st.type.fields()" "get fields from st.type" 1
gdb_test "python print (len(fields))" "2" "Check number of fields (st)"
gdb_test "python print (fields\[0\].name)" "a" "Check structure field a name"
gdb_test "python print (fields\[1\].name)" "b" "Check structure field b name"
# Test that unamed fields have 'None' for name.
gdb_py_test_silent_cmd "python ss = gdb.parse_and_eval('ss')" "init ss" 1
gdb_py_test_silent_cmd "python ss_fields = ss.type.fields()" \
"get fields from ss.type" 1
gdb_test "python print(len(ss_fields))" "2" "Check length of ss_fields"
gdb_test "python print(ss_fields\[0\].name is None)" "True" \
"Check ss_fields\[0\].name"
gdb_test "python print(ss_fields\[1\].name is None)" "True" \
"Check ss_fields\[1\].name"
# Regression test for
# http://sourceware.org/bugzilla/show_bug.cgi?id=12070.
gdb_test "python print ('type' in dir(fields\[0\]))" "True" \
"Check that dir includes name"
# Test Python mapping behavior of gdb.Type for structs/classes
gdb_test "python print (len(st.type))" "2" "Check number of fields (st.type)"
gdb_test "python print (st.type\['a'\].name)" "a" "Check fields lookup by name"
gdb_test "python print (\[v.bitpos for v in st.type.itervalues()\])" {\[0L?, 32L?\]} "Check fields iteration over values"
gdb_test "python print (\[(n, v.bitpos) for (n, v) in st.type.items()\])" {\[\('a', 0L?\), \('b', 32L?\)\]} "Check fields items list"
gdb_test "python print ('a' in st.type)" "True" "Check field name exists test"
gdb_test "python print ('nosuch' in st.type)" "False" "Check field name nonexists test"
gdb_test "python print (not not st.type)" "True" "Check conversion to bool"
# Test rejection of mapping operations on scalar types
gdb_test "python print (len (st.type\['a'\].type))" "TypeError: Type is not a structure, union, enum, or function type.*"
gdb_test "python print (st.type\['a'\].type.has_key ('x'))" "TypeError: Type is not a structure, union, enum, or function type.*"
gdb_test "python print (st.type\['a'\].type\['x'\])" "TypeError: Type is not a structure, union, enum, or function type.*"
gdb_test "python print (st.type\['a'\].type.keys ())" "TypeError: Type is not a structure, union, enum, or function type.*"
# Test conversion to bool on scalar types
gdb_test "python print (not not st.type\['a'\].type)" "True"
# Test regression PR python/10805
gdb_py_test_silent_cmd "print (ar)" "print value (ar)" 1
gdb_py_test_silent_cmd "python ar = gdb.history (0)" "get value (ar) from history" 1
gdb_test "python fields = ar.type.fields()"
gdb_test "python print (len(fields))" "1" "Check the number of fields"
gdb_test "python print (fields\[0\].type)" "<range type>" "Check array field type"
# Test gdb.Type.array.
gdb_test "python print (ar\[0\].cast(ar\[0\].type.array(1)))" \
".1, 2." "cast to array with one argument"
gdb_test "python print (ar\[0\].cast(ar\[0\].type.array(0, 1)))" \
".1, 2." "cast to array with two arguments"
gdb_test "python print (ar\[0\].type == ar\[0\].type)" "True"
# Test gdb.Type.vector.
# Note: vectors cast differently than arrays. Here ar[0] is replicated
# for the size of the vector.
gdb_py_test_silent_cmd "print (vec_data_1)" "print value (vec_data_1)" 1
gdb_py_test_silent_cmd "python vec_data_1 = gdb.history (0)" "get value (vec_data_1) from history" 1
gdb_py_test_silent_cmd "print (vec_data_2)" "print value (vec_data_2)" 1
gdb_py_test_silent_cmd "python vec_data_2 = gdb.history (0)" "get value (vec_data_2) from history" 1
gdb_py_test_silent_cmd "python vec1 = vec_data_1.cast(ar\[0\].type.vector(1))" "set vec1" 1
gdb_test "python print (vec1)" ".1, 1." "cast to vector with one argument"
gdb_py_test_silent_cmd "python vec2 = vec_data_1.cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
gdb_test "python print (vec2)" ".1, 1." "cast to vector with two arguments"
gdb_test "python print (vec1 == vec2)" "True"
gdb_py_test_silent_cmd "python vec3 = vec_data_2.cast(ar\[0\].type.vector(1))" "set vec3" 1
gdb_test "python print (vec1 == vec3)" "False"
# Test fields of a function (its parameters)
gdb_test "python print (len (gdb.parse_and_eval ('a_function').type.fields ()))" "2"
gdb_test "python print (gdb.parse_and_eval ('a_function').type.fields ()\[0\].type)" "int"
gdb_test "python print (gdb.parse_and_eval ('a_function').type.fields ()\[1\].type)" "char"
}
}
proc test_enums {} {
with_test_prefix "test_enum" {
gdb_py_test_silent_cmd "print (e)" "print value (e)" 1
gdb_py_test_silent_cmd "python (e) = gdb.history (0)" "get value (e) from history" 1
gdb_py_test_silent_cmd "python fields = e.type.fields()" "extract type fields from e" 1
gdb_test "python print (len(fields))" "3" "Check the number of enum fields"
gdb_test "python print (fields\[0\].name)" "v1" "Check enum field\[0\] name"
gdb_test "python print (fields\[1\].name)" "v2" "Check enum field\[1\]name"
# Ditto but by mapping operations
gdb_test "python print (len(e.type))" "3" "Check the number of type fields"
gdb_test "python print (e.type\['v1'\].name)" "v1" "Check enum field lookup by name (v1)"
gdb_test "python print (e.type\['v3'\].name)" "v3" "Check enum field lookup by name (v3)"
gdb_test "python print (\[v.enumval for v in e.type.itervalues()\])" {\[0L?, 1L?, 2L?\]} "Check num fields iteration over values"
gdb_test "python print (\[(n, v.enumval) for (n, v) in e.type.items()\])" {\[\('v1', 0L?\), \('v2', 1L?\), \('v3', 2L?\)\]} "Check enum fields items list"
}
}
proc test_base_class {} {
with_test_prefix "test_base_class" {
gdb_py_test_silent_cmd "print (d)" "print value (d)" 1
gdb_py_test_silent_cmd "python d = gdb.history (0)" "get value (d) from history" 1
gdb_py_test_silent_cmd "python fields = d.type.fields()" "extract type fields from d" 1
gdb_test "python print (len(fields))" "3" "Check the number of fields"
gdb_test "python print (fields\[0\].is_base_class)" "True" "Check base class (fields\[0\])"
gdb_test "python print (fields\[1\].is_base_class)" "False" "Check base class (fields\[1\])"
}
}
proc test_range {} {
with_test_prefix "test_range" {
with_test_prefix "on ranged value" {
# Test a valid range request.
gdb_py_test_silent_cmd "print (ar)" "print value (ar)" 1
gdb_py_test_silent_cmd "python ar = gdb.history (0)" "get value (ar) from history" 1
gdb_test "python print (len(ar.type.range()))" "2" "Check correct tuple length"
gdb_test "python print (ar.type.range()\[0\])" "0" "Check range low bound"
gdb_test "python print (ar.type.range()\[1\])" "1" "Check range high bound"
}
with_test_prefix "on ranged type" {
# Test a range request on a ranged type.
gdb_py_test_silent_cmd "print (ar)" "print value (ar)" 1
gdb_py_test_silent_cmd "python ar = gdb.history (0)" "get value (ar) from history" 1
gdb_py_test_silent_cmd "python fields = ar.type.fields()" "get fields" 1
gdb_test "python print (fields\[0\].type.range()\[0\])" "0" "Check range low bound"
gdb_test "python print (fields\[0\].type.range()\[1\])" "1" "Check range high bound"
}
with_test_prefix "on unranged value" {
# Test where a range does not exist.
gdb_py_test_silent_cmd "print (st)" "print value (st)" 1
gdb_py_test_silent_cmd "python st = gdb.history (0)" "get value (st) from history" 1
gdb_test "python print (st.type.range())" "RuntimeError: This type does not have a range.*" "Check range for non ranged type."
}
}
}
# Some tests of template arguments.
proc test_template {} {
gdb_py_test_silent_cmd \
"python ttype = gdb.parse_and_eval('temvar').type" \
"get type of temvar" \
1
gdb_test "python print (ttype.template_argument(0))" "D"
gdb_test "python print (isinstance(ttype.template_argument(0), gdb.Type))" \
"True"
# The next two tests require a GCC that emits DW_TAG_template_*.
# GCC 4.4 does not emit it, 4.5 and 6 do emit it.
set have_older_gcc 0
if {[test_compiler_info {gcc-[0-3]-*}]
|| [test_compiler_info {gcc-4-[0-4]-*}]} {
set have_older_gcc 1
}
if $have_older_gcc { setup_xfail *-*-* }
gdb_test "python print (ttype.template_argument(1))" "23"
if $have_older_gcc { setup_xfail *-*-* }
gdb_test "python print (isinstance(ttype.template_argument(1), gdb.Value))" \
"True"
if {[test_compiler_info {gcc-[0-3]-*}]
|| [test_compiler_info {gcc-4-[0-5]-*}]} {
setup_xfail "gcc/46955" *-*-*
}
gdb_test "python print (ttype.template_argument(2))" "&C::c"
}
# Perform C Tests.
if { [build_inferior "${binfile}" "c"] == 0 } {
restart_gdb "${binfile}"
# Skip all tests if Python scripting is not enabled.
if { [skip_python_tests] } { continue }
gdb_test "python print(gdb.lookup_type('char').array(1, 0))" \
"char \\\[0\\\]"
gdb_test "python print(gdb.lookup_type('char').array(1, -1))" \
"Array length must not be negative.*"
gdb_test "python print(gdb.lookup_type('int').optimized_out())" \
"<optimized out>"
with_test_prefix "lang_c" {
runto_bp "break to inspect struct and array."
test_fields "c"
test_enums
}
}
# Perform C++ Tests.
if { [build_inferior "${binfile}-cxx" "c++"] == 0 } {
restart_gdb "${binfile}-cxx"
with_test_prefix "lang_cpp" {
runto_bp "break to inspect struct and array."
test_fields "c++"
test_base_class
test_range
test_template
test_enums
}
}
|