aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.python/py-exec-file.exp
blob: f73575707a41361fa188cde24b6a8d074fbe9549 (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
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
# Copyright (C) 2023-2024 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/>.

require allow_python_tests

load_lib gdb-python.exp

standard_testfile

set binfile1 ${binfile}-a
set binfile2 ${binfile}-b

if {[build_executable "failed to prepare first executable" \
	 $binfile1 $srcfile]} {
    return -1
}

if {[build_executable "failed to prepare second executable" \
	 $binfile2 $srcfile]} {
    return -1
}

set binfile1 [gdb_remote_download host $binfile1]
set binfile2 [gdb_remote_download host $binfile2]

# Setup a Python function to listen for the executable changed event.
proc setup_exec_change_handler {} {
    gdb_py_test_silent_cmd \
	[multi_line \
	     "python" \
	     "def reset_state():" \
	     "   global exec_changed_state" \
	     "   exec_changed_state = \[0, None, None\]" \
	     "end" ] \
	"build reset_state function" 0

    gdb_py_test_silent_cmd \
	[multi_line \
	     "python" \
	     "def executable_changed(event):" \
	     "   global exec_changed_state" \
	     "   exec_changed_state\[0\] += 1" \
	     "   exec_changed_state\[1\] = event.progspace.executable_filename" \
	     "   exec_changed_state\[2\] = event.reload" \
	     "end" ] \
	"build executable_changed function" 0

    gdb_test_no_output -nopass "python reset_state()"
    gdb_test_no_output "python gdb.events.executable_changed.connect(executable_changed)"
}

# Check the global Python state that is updated when the
# executable_changed event occurs, and then reset the global state.
# FILENAME is a string, the name of the new executable file.  RELOAD
# is a string, which should be 'True' or 'False', and represents if
# the executable file was reloaded, or changed.
proc check_exec_change { filename_re reload testname } {
    if { $filename_re ne "None" } {
	set filename_re "'$filename_re'"
    }
    if { $filename_re eq "None" && $reload eq "None" } {
	set count 0
    } else {
	set count 1
    }
    gdb_test "python print(exec_changed_state)" \
	"\\\[$count, $filename_re, $reload\\\]" \
	$testname
    gdb_test_no_output -nopass "python reset_state()"
}

# Check that the executable_filename is set correctly after using the
# 'file' command.
with_test_prefix "using 'file' command" {
    clean_restart

    setup_exec_change_handler

    gdb_test "python print(gdb.current_progspace().executable_filename)" \
	"None" \
	"check executable_filename when no file is loaded"

    gdb_test "file $binfile1" \
	"Reading symbols from [string_to_regexp $binfile1]\\.\\.\\..*" \
	"load first executable"
    gdb_test "python print(gdb.current_progspace().executable_filename)" \
	"[string_to_regexp $binfile1]" \
	"check executable_filename when first executable is loaded"

    check_exec_change [string_to_regexp $binfile1] False \
	"check executable_changed state after first executable was loaded"

    gdb_test "file $binfile2" \
	"Reading symbols from [string_to_regexp $binfile2]\\.\\.\\..*" \
	"load second executable" \
	"Load new symbol table from .*\? .y or n. " "y"
    gdb_test "python print(gdb.current_progspace().executable_filename)" \
	"[string_to_regexp $binfile2]" \
	"check executable_filename when second executable is loaded"

    check_exec_change [string_to_regexp $binfile2] False \
	"check executable_changed state after second executable was loaded"

    gdb_unload
    gdb_test "python print(gdb.current_progspace().executable_filename)" \
	"None" \
	"check executable_filename after unloading file"

    check_exec_change None False \
	"check executable_changed state after unloading the executable"
}

# Check that the executable_filename is correctly set when we only set
# the exec-file.
with_test_prefix "using 'exec-file' command" {
    clean_restart

    setup_exec_change_handler

    gdb_test_no_output "exec-file $binfile1" \
	"load first executable"
    gdb_test "python print(gdb.current_progspace().executable_filename)" \
	"[string_to_regexp $binfile1]" \
	"check executable_filename when first executable is loaded"

    check_exec_change [string_to_regexp $binfile1] False \
	"check executable_changed state after first executable was loaded"

    gdb_test_no_output "exec-file $binfile2" \
	"load second executable"
    gdb_test "python print(gdb.current_progspace().executable_filename)" \
	"[string_to_regexp $binfile2]" \
	"check executable_filename when second executable is loaded"

    check_exec_change [string_to_regexp $binfile2] False \
	"check executable_changed state after second executable was loaded"

    gdb_test "exec-file" "No executable file now\\."
    gdb_test "python print(gdb.current_progspace().executable_filename)" \
	"None" \
	"check executable_filename after unloading file"

    check_exec_change None False \
	"check executable_changed state after unloading the executable"
}

# Check that setting the symbol-file doesn't cause the
# executable_filename to be set.
with_test_prefix "using 'symbol-file' command" {
    clean_restart

    setup_exec_change_handler

    gdb_test "symbol-file $binfile1" \
	"Reading symbols from [string_to_regexp $binfile1]\\.\\.\\..*" \
	"load first executable"
    gdb_test "python print(gdb.current_progspace().executable_filename)" \
	"None" \
	"check executable_filename after setting symbol-file"

    check_exec_change None None \
	"check executable_changed state after setting symbol-file"
}

# Check the executable_changed event when the executable changes on disk.
with_test_prefix "exec changes on disk" {
    clean_restart $binfile1

    setup_exec_change_handler

    runto_main

    gdb_test_no_output "shell sleep 1" \
	"ensure executable is at least 1 second old"

    gdb_test "shell touch ${binfile1}" "" \
	"update the executable on disk"

    runto_main

    check_exec_change [string_to_regexp $binfile1] True \
	"check executable_changed state after exec changed on disk"
}