aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.gdb/python-helper.exp
blob: 7013a3a836fd14f411f50f6df23142b55d6e9b7a (plain)
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
# Copyright 2021 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 test exercises the gdb-gdb.py helper script that is generated
# into the GDB build directory.  This script is intended for use by
# developers to make debugging GDB easier.

load_lib selftest-support.exp

if [target_info exists gdb,noinferiorio] {
    verbose "Skipping because of no inferiorio capabilities."
    return
}

# Find the helper script in the GDB build directory.
set py_helper_script [file dirname $GDB]/gdb-gdb.py
if { ![file readable $py_helper_script] \
	 || [file type $py_helper_script] != "file" } {
    untested "failed to find gdb-gdb.py helper script"
    return
}

# Start GDB and check that we have python support.
gdb_start
if { [skip_python_tests] } {
    untested "skipped gdb-gdb.py tests due to lack of python support"
    return
}
gdb_exit

# The main test.  This is called by the self-test framework once GDB
# has been started on a copy of itself.
proc test_python_helper {} {
    global py_helper_script decimal hex gdb_prompt
    global inferior_spawn_id

    # Source the python helper script.  This script registers the
    # pretty printer for the object file called 'gdb', however, in our
    # selftests we rename 'gdb' to 'xgdb', so the pretty printer
    # doesn't get registered by default.
    #
    # So, after sourcing the script we do our own objfile scan and
    # register the pretty printer for the objfile called 'xgdb'.
    gdb_test_no_output "source $py_helper_script" \
	"source gdb-gdb.py helper script"
    gdb_test [multi_line_input \
		  "python" \
		  "for objfile in gdb.objfiles():" \
		  "  if os.path.basename(objfile.filename) == \"xgdb\":" \
		  "    objfile.pretty_printers.append(type_lookup_function)" \
		  "end"] ".*" \
	"register the type pretty printer"

    # Now place a breakpoint somewhere useful.  This can be any function that:
    # (a) is easy to reach by issuing a simple gdb command, and
    # (b) is unlikely to be modified very often within gdb, and
    # (c) has a parameter that is either a 'struct type *' or a 'struct value *'.
    gdb_breakpoint value_print

    # Adjust the prompt on the outer gdb, this just makes things a
    # little clearer when trying to unpick which GDB is active.
    gdb_test_multiple "set prompt (xgdb) " "set xgdb prompt" {
	-re "\[(\]xgdb\[)\].*\[(\]xgdb\[)\] $" {
	    pass $gdb_test_name
	}
    }

    # Send a command to the outer GDB to continue the inner GDB.  The
    # stop is being detected from the inner GDB, hence the use of -i
    # here.
    gdb_test_multiple "continue" "start inner gdb" {
	-i "$inferior_spawn_id"
	-re "\r\n$gdb_prompt $" {
	    pass $gdb_test_name
	}
    }

    # Send a command to the inner GDB (hence send_inferior), this
    # should result in the outer GDB stopping at the breakpoint we
    # just created.
    send_inferior "print 1\n"
    gdb_test_multiple "" "hit breakpoint in inner gdb" {
	-re "Breakpoint $decimal, value_print.*\\(xgdb\\) $" {
	    pass $gdb_test_name
	}
    }

    # Now inspect the type of parameter VAL, this should trigger the
    # pretty printers.
    set answer [multi_line \
		    "${decimal} = " \
		    "{pointer_type = 0x0," \
		    " reference_type = 0x0," \
		    " chain = 0x0," \
		    " instance_flags = 0," \
		    " length = $decimal," \
		    " main_type = $hex}" \
		    "\\(xgdb\\) $"]
    gdb_test_multiple "print *val->type" "pretty print type" {
	-re "$answer" {
	    pass $gdb_test_name
	}
	-re "There is no member named.*\r\n\\(xgdb\\) $" {
	    fail $gdb_test_name
	}
    }

    set answer [multi_line \
		    "$decimal = " \
		    "{name = $hex \"int\"," \
		    " code = TYPE_CODE_INT," \
		    " flags = \[^\r\n\]+," \
		    " owner = $hex \\(gdbarch\\)," \
		    " target_type = 0x0," \
		    " type_specific_field = TYPE_SPECIFIC_NONE}" \
		    "\\(xgdb\\) $"]
    gdb_test_multiple "print *val->type->main_type" "pretty print type->main_type" {
	-re "$answer" {
	    pass $gdb_test_name
	}
	-re "There is no member named.*\r\n\\(xgdb\\) $" {
	    fail $gdb_test_name
	}
    }

    return 0
}

# Use the self-test framework to run the test.
do_self_tests captured_main test_python_helper