Home | History | Annotate | Line # | Download | only in gdb.python
      1  1.1  christos # Copyright (C) 2023-2024 Free Software Foundation, Inc.
      2  1.1  christos 
      3  1.1  christos # This program is free software; you can redistribute it and/or modify
      4  1.1  christos # it under the terms of the GNU General Public License as published by
      5  1.1  christos # the Free Software Foundation; either version 3 of the License, or
      6  1.1  christos # (at your option) any later version.
      7  1.1  christos #
      8  1.1  christos # This program is distributed in the hope that it will be useful,
      9  1.1  christos # but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  1.1  christos # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11  1.1  christos # GNU General Public License for more details.
     12  1.1  christos #
     13  1.1  christos # You should have received a copy of the GNU General Public License
     14  1.1  christos # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15  1.1  christos 
     16  1.1  christos load_lib gdb-python.exp
     17  1.1  christos 
     18  1.1  christos require allow_python_tests
     19  1.1  christos 
     20  1.1  christos standard_testfile
     21  1.1  christos 
     22  1.1  christos if {[build_executable "failed to prepare" ${testfile} ${srcfile}]} {
     23  1.1  christos     return -1
     24  1.1  christos }
     25  1.1  christos 
     26  1.1  christos # Remove debug information from BINFILE and place it into
     27  1.1  christos # BINFILE.debug.
     28  1.1  christos if {[gdb_gnu_strip_debug $binfile]} {
     29  1.1  christos     unsupported "cannot produce separate debug info files"
     30  1.1  christos     return -1
     31  1.1  christos }
     32  1.1  christos 
     33  1.1  christos set remote_python_file \
     34  1.1  christos     [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py]
     35  1.1  christos 
     36  1.1  christos set debug_filename ${binfile}.debug
     37  1.1  christos set hidden_filename ${binfile}.hidden
     38  1.1  christos 
     39  1.1  christos # Start GDB.
     40  1.1  christos clean_restart
     41  1.1  christos 
     42  1.1  christos # Some initial sanity checks; initially, we can find the debug information
     43  1.1  christos # (this will use the .gnu_debuglink), then after we move the debug
     44  1.1  christos # information, reload the executable, now the debug can't be found.
     45  1.1  christos with_test_prefix "initial checks" {
     46  1.1  christos     # Load BINFILE, we should find the separate debug information.
     47  1.1  christos     gdb_file_cmd $binfile
     48  1.1  christos     gdb_assert {$gdb_file_cmd_debug_info == "debug"} \
     49  1.1  christos 	"debug info is found"
     50  1.1  christos 
     51  1.1  christos     # Rename the debug information file, re-load BINFILE, GDB should fail
     52  1.1  christos     # to find the debug information
     53  1.1  christos     remote_exec build "mv $debug_filename $hidden_filename"
     54  1.1  christos     gdb_file_cmd $binfile
     55  1.1  christos     gdb_assert {$gdb_file_cmd_debug_info == "nodebug"} \
     56  1.1  christos 	"debug info no longer found"
     57  1.1  christos }
     58  1.1  christos 
     59  1.1  christos # Load the Python script into GDB.
     60  1.1  christos gdb_test "source $remote_python_file" "^Success" \
     61  1.1  christos     "source python script"
     62  1.1  christos 
     63  1.1  christos # Setup the separate debug info directory.  This isn't actually needed until
     64  1.1  christos # some of the later tests, but might as well get this done now.
     65  1.1  christos set debug_directory [standard_output_file "debug-dir"]
     66  1.1  christos remote_exec build "mkdir -p $debug_directory"
     67  1.1  christos gdb_test_no_output "set debug-file-directory $debug_directory" \
     68  1.1  christos     "set debug-file-directory"
     69  1.1  christos 
     70  1.1  christos # Initially the missing debug handler we install is in a mode where it
     71  1.1  christos # returns None, indicating that it can't help locate the debug information.
     72  1.1  christos # Check this works as expected.
     73  1.1  christos with_test_prefix "handler returning None" {
     74  1.1  christos     gdb_test_no_output \
     75  1.1  christos 	"python gdb.missing_debug.register_handler(None, handler_obj)" \
     76  1.1  christos 	"register the initial handler"
     77  1.1  christos 
     78  1.1  christos     gdb_file_cmd $binfile
     79  1.1  christos     gdb_assert {$gdb_file_cmd_debug_info == "nodebug"} \
     80  1.1  christos 	"debug info not found"
     81  1.1  christos 
     82  1.1  christos     # Check the handler was only called once.
     83  1.1  christos     gdb_test "python print(handler_obj.call_count)" "^1" \
     84  1.1  christos 	"check handler was only called once"
     85  1.1  christos }
     86  1.1  christos 
     87  1.1  christos # Now configure the handler to move the debug file back to the
     88  1.1  christos # .gnu_debuglink location and then return True, this will cause GDB to
     89  1.1  christos # recheck, at which point it should find the debug info.
     90  1.1  christos with_test_prefix "handler in gnu_debuglink mode" {
     91  1.1  christos     gdb_test_no_output "python handler_obj.set_mode(Mode.RETURN_TRUE, \
     92  1.1  christos 						    \"$hidden_filename\", \
     93  1.1  christos 						    \"$debug_filename\")" \
     94  1.1  christos 	"confirgure handler"
     95  1.1  christos     gdb_file_cmd $binfile
     96  1.1  christos     gdb_assert {$gdb_file_cmd_debug_info == "debug"} "debug info found"
     97  1.1  christos 
     98  1.1  christos     # Check the handler was only called once.
     99  1.1  christos     gdb_test "python print(handler_obj.call_count)" "^1" \
    100  1.1  christos 	"check handler was only called once"
    101  1.1  christos }
    102  1.1  christos 
    103  1.1  christos # Setup a directory structure based on the build-id of BINFILE, but don't
    104  1.1  christos # move the debug information into place just yet.
    105  1.1  christos #
    106  1.1  christos # Instead, configure the handler to move the debug info into the build-id
    107  1.1  christos # directory.
    108  1.1  christos #
    109  1.1  christos # Reload BINFILE, at which point the handler will move the debug info into
    110  1.1  christos # the build-id directory and return True, GDB will then recheck for the
    111  1.1  christos # debug information, and should find it.
    112  1.1  christos with_test_prefix "handler in build-id mode" {
    113  1.1  christos     # Move the debug file out of the way once more.
    114  1.1  christos     remote_exec build "mv $debug_filename $hidden_filename"
    115  1.1  christos 
    116  1.1  christos     # Create the build-id based directory in which the debug information
    117  1.1  christos     # will be placed.
    118  1.1  christos     set build_id_filename \
    119  1.1  christos 	$debug_directory/[build_id_debug_filename_get $binfile]
    120  1.1  christos     remote_exec build "mkdir -p [file dirname $build_id_filename]"
    121  1.1  christos 
    122  1.1  christos     # Configure the handler to move the debug info into the build-id dir.
    123  1.1  christos     gdb_test_no_output "python handler_obj.set_mode(Mode.RETURN_TRUE, \
    124  1.1  christos 						    \"$hidden_filename\", \
    125  1.1  christos 						    \"$build_id_filename\")" \
    126  1.1  christos 	"confirgure handler"
    127  1.1  christos 
    128  1.1  christos     # Reload the binary and check the debug information is found.
    129  1.1  christos     gdb_file_cmd $binfile
    130  1.1  christos     gdb_assert {$gdb_file_cmd_debug_info == "debug"} "debug info found"
    131  1.1  christos 
    132  1.1  christos     # Check the handler was only called once.
    133  1.1  christos     gdb_test "python print(handler_obj.call_count)" "^1" \
    134  1.1  christos 	"check handler was only called once"
    135  1.1  christos }
    136  1.1  christos 
    137  1.1  christos # Move the debug information back to a hidden location and configure the
    138  1.1  christos # handler to return the filename of the hidden debug info location.  GDB
    139  1.1  christos # should immediately use this file as the debug information.
    140  1.1  christos with_test_prefix "handler returning a string" {
    141  1.1  christos     remote_exec build "mv $build_id_filename $hidden_filename"
    142  1.1  christos 
    143  1.1  christos     # Configure the handler return a filename string.
    144  1.1  christos     gdb_test_no_output "python handler_obj.set_mode(Mode.RETURN_STRING, \
    145  1.1  christos 						    \"$hidden_filename\")" \
    146  1.1  christos 	"confirgure handler"
    147  1.1  christos 
    148  1.1  christos     # Reload the binary and check the debug information is found.
    149  1.1  christos     gdb_file_cmd $binfile
    150  1.1  christos     gdb_assert {$gdb_file_cmd_debug_info == "debug"} "debug info found"
    151  1.1  christos 
    152  1.1  christos     # Check the handler was only called once.
    153  1.1  christos     gdb_test "python print(handler_obj.call_count)" "^1" \
    154  1.1  christos 	"check handler was only called once"
    155  1.1  christos }
    156  1.1  christos 
    157  1.1  christos # Register another global handler, this one raises an exception.  Reload the
    158  1.1  christos # debug information, the bad handler should be invoked first, which raises
    159  1.1  christos # an excetption, at which point GDB should skip further Python handlers.
    160  1.1  christos with_test_prefix "handler raises an exception" {
    161  1.1  christos     gdb_test_no_output \
    162  1.1  christos 	"python gdb.missing_debug.register_handler(None, rhandler)"
    163  1.1  christos 
    164  1.1  christos     foreach_with_prefix exception_type {gdb.GdbError TypeError} {
    165  1.1  christos 	gdb_test_no_output \
    166  1.1  christos 	    "python rhandler.exception_type = $exception_type"
    167  1.1  christos 
    168  1.1  christos 	gdb_file_cmd $binfile
    169  1.1  christos 	gdb_assert {$gdb_file_cmd_debug_info == "nodebug"} \
    170  1.1  christos 	    "debug info not found"
    171  1.1  christos 
    172  1.1  christos 	set re [string_to_regexp \
    173  1.1  christos 		    "Python Exception <class '$exception_type'>: message"]
    174  1.1  christos 	gdb_assert {[regexp $re $gdb_file_cmd_msg]} \
    175  1.1  christos 	    "check for exception in file command output"
    176  1.1  christos 
    177  1.1  christos 	# Our original handler is still registered, but should not have been
    178  1.1  christos 	# called again (as the exception occurs first).
    179  1.1  christos 	gdb_test "python print(handler_obj.call_count)" "^1" \
    180  1.1  christos 	    "check good handler hasn't been called again"
    181  1.1  christos     }
    182  1.1  christos }
    183  1.1  christos 
    184  1.1  christos gdb_test "info missing-debug-handlers" \
    185  1.1  christos     [multi_line \
    186  1.1  christos 	 "Global:" \
    187  1.1  christos 	 "  exception_handler" \
    188  1.1  christos 	 "  handler"] \
    189  1.1  christos     "check both handlers are visible"
    190  1.1  christos 
    191  1.1  christos # Re-start GDB.
    192  1.1  christos clean_restart
    193  1.1  christos 
    194  1.1  christos # Load the Python script into GDB.
    195  1.1  christos gdb_test "source $remote_python_file" "^Success" \
    196  1.1  christos     "source python script for bad handler name checks"
    197  1.1  christos 
    198  1.1  christos # Attempt to register a missing-debug-handler with NAME.  The expectation is
    199  1.1  christos # that this should fail as NAME contains some invalid characters.
    200  1.1  christos proc check_bad_name {name} {
    201  1.1  christos     set name_re [string_to_regexp $name]
    202  1.1  christos     set re \
    203  1.1  christos 	[multi_line \
    204  1.1  christos 	     "ValueError.*: invalid character '.' in handler name: $name_re" \
    205  1.1  christos 	     "Error occurred in Python.*"]
    206  1.1  christos 
    207  1.1  christos     gdb_test "python register(\"$name\")" $re \
    208  1.1  christos 	"check that '$name' is not accepted"
    209  1.1  christos }
    210  1.1  christos 
    211  1.1  christos # We don't attempt to be exhaustive here, just check a few random examples
    212  1.1  christos # of invalid names.
    213  1.1  christos check_bad_name "!! Bad Name"
    214  1.1  christos check_bad_name "Bad Name"
    215  1.1  christos check_bad_name "(Bad Name)"
    216  1.1  christos check_bad_name "Bad \[Name\]"
    217  1.1  christos check_bad_name "Bad,Name"
    218  1.1  christos check_bad_name "Bad;Name"
    219  1.1  christos 
    220  1.1  christos # Check that there are no handlers registered.
    221  1.1  christos gdb_test_no_output "info missing-debug-handlers" \
    222  1.1  christos     "check no handlers are registered"
    223  1.1  christos 
    224  1.1  christos # Check we can use the enable/disable commands where there are no handlers
    225  1.1  christos # registered.
    226  1.1  christos gdb_test "enable missing-debug-handler foo" \
    227  1.1  christos     "^0 missing debug handlers enabled"
    228  1.1  christos gdb_test "disable missing-debug-handler foo" \
    229  1.1  christos     "^0 missing debug handlers disabled"
    230  1.1  christos 
    231  1.1  christos # Grab the current program space object, used for registering handler later.
    232  1.1  christos gdb_test_no_output "python pspace = gdb.selected_inferior().progspace"
    233  1.1  christos 
    234  1.1  christos # Now register some handlers.
    235  1.1  christos foreach hspec {{\"Foo\" None}
    236  1.1  christos     {\"-bar\" None}
    237  1.1  christos     {\"baz-\" pspace}
    238  1.1  christos     {\"abc-def\" pspace}} {
    239  1.1  christos     lassign $hspec name locus
    240  1.1  christos     gdb_test "python register($name, $locus)"
    241  1.1  christos }
    242  1.1  christos 
    243  1.1  christos with_test_prefix "all handlers enabled" {
    244  1.1  christos     gdb_test "info missing-debug-handlers" \
    245  1.1  christos 	[multi_line \
    246  1.1  christos 	     "Current Progspace:" \
    247  1.1  christos 	     "  abc-def" \
    248  1.1  christos 	     "  baz-" \
    249  1.1  christos 	     "Global:" \
    250  1.1  christos 	     "  -bar" \
    251  1.1  christos 	     "  Foo"]
    252  1.1  christos 
    253  1.1  christos     gdb_file_cmd $binfile
    254  1.1  christos     gdb_test "python print(handler_call_log)" \
    255  1.1  christos 	[string_to_regexp {['abc-def', 'baz-', '-bar', 'Foo']}]
    256  1.1  christos     gdb_test_no_output "python handler_call_log = \[\]" \
    257  1.1  christos 	"reset call log"
    258  1.1  christos }
    259  1.1  christos 
    260  1.1  christos with_test_prefix "disable 'baz-'" {
    261  1.1  christos     gdb_test "disable missing-debug-handler progspace baz-" \
    262  1.1  christos 	"^1 missing debug handler disabled"
    263  1.1  christos 
    264  1.1  christos     gdb_test "info missing-debug-handlers" \
    265  1.1  christos 	[multi_line \
    266  1.1  christos 	     "Progspace \[^\r\n\]+:" \
    267  1.1  christos 	     "  abc-def" \
    268  1.1  christos 	     "  baz- \\\[disabled\\\]" \
    269  1.1  christos 	     "Global:" \
    270  1.1  christos 	     "  -bar" \
    271  1.1  christos 	     "  Foo"]
    272  1.1  christos 
    273  1.1  christos     gdb_file_cmd $binfile
    274  1.1  christos     gdb_test "python print(handler_call_log)" \
    275  1.1  christos 	[string_to_regexp {['abc-def', '-bar', 'Foo']}]
    276  1.1  christos     gdb_test_no_output "python handler_call_log = \[\]" \
    277  1.1  christos 	"reset call log"
    278  1.1  christos }
    279  1.1  christos 
    280  1.1  christos with_test_prefix "disable 'Foo'" {
    281  1.1  christos     gdb_test "disable missing-debug-handler .* Foo" \
    282  1.1  christos 	"^1 missing debug handler disabled"
    283  1.1  christos 
    284  1.1  christos     gdb_test "info missing-debug-handlers" \
    285  1.1  christos 	[multi_line \
    286  1.1  christos 	     "Progspace \[^\r\n\]+:" \
    287  1.1  christos 	     "  abc-def" \
    288  1.1  christos 	     "  baz- \\\[disabled\\\]" \
    289  1.1  christos 	     "Global:" \
    290  1.1  christos 	     "  -bar" \
    291  1.1  christos 	     "  Foo \\\[disabled\\\]"]
    292  1.1  christos 
    293  1.1  christos     gdb_file_cmd $binfile
    294  1.1  christos     gdb_test "python print(handler_call_log)" \
    295  1.1  christos 	[string_to_regexp {['abc-def', '-bar']}]
    296  1.1  christos     gdb_test_no_output "python handler_call_log = \[\]" \
    297  1.1  christos 	"reset call log"
    298  1.1  christos }
    299  1.1  christos 
    300  1.1  christos with_test_prefix "disable everything" {
    301  1.1  christos     gdb_test "disable missing-debug-handler .* .*" \
    302  1.1  christos 	"^2 missing debug handlers disabled"
    303  1.1  christos 
    304  1.1  christos     gdb_test "info missing-debug-handlers" \
    305  1.1  christos 	[multi_line \
    306  1.1  christos 	     "Progspace \[^\r\n\]+:" \
    307  1.1  christos 	     "  abc-def \\\[disabled\\\]" \
    308  1.1  christos 	     "  baz- \\\[disabled\\\]" \
    309  1.1  christos 	     "Global:" \
    310  1.1  christos 	     "  -bar \\\[disabled\\\]" \
    311  1.1  christos 	     "  Foo \\\[disabled\\\]"]
    312  1.1  christos 
    313  1.1  christos     gdb_file_cmd $binfile
    314  1.1  christos     gdb_test "python print(handler_call_log)" \
    315  1.1  christos 	[string_to_regexp {[]}]
    316  1.1  christos     gdb_test_no_output "python handler_call_log = \[\]" \
    317  1.1  christos 	"reset call log"
    318  1.1  christos }
    319  1.1  christos 
    320  1.1  christos with_test_prefix "enable 'abc-def'" {
    321  1.1  christos     set re [string_to_regexp $binfile]
    322  1.1  christos 
    323  1.1  christos     gdb_test "enable missing-debug-handler \"$re\" abc-def" \
    324  1.1  christos 	"^1 missing debug handler enabled" \
    325  1.1  christos 	"enable missing-debug-handler"
    326  1.1  christos 
    327  1.1  christos     gdb_test "info missing-debug-handlers" \
    328  1.1  christos 	[multi_line \
    329  1.1  christos 	     "Progspace \[^\r\n\]+:" \
    330  1.1  christos 	     "  abc-def" \
    331  1.1  christos 	     "  baz- \\\[disabled\\\]" \
    332  1.1  christos 	     "Global:" \
    333  1.1  christos 	     "  -bar \\\[disabled\\\]" \
    334  1.1  christos 	     "  Foo \\\[disabled\\\]"]
    335  1.1  christos 
    336  1.1  christos     gdb_file_cmd $binfile
    337  1.1  christos     gdb_test "python print(handler_call_log)" \
    338  1.1  christos 	[string_to_regexp {['abc-def']}]
    339  1.1  christos     gdb_test_no_output "python handler_call_log = \[\]" \
    340  1.1  christos 	"reset call log"
    341  1.1  christos }
    342  1.1  christos 
    343  1.1  christos with_test_prefix "enable global handlers" {
    344  1.1  christos     set re [string_to_regexp $binfile]
    345  1.1  christos 
    346  1.1  christos     gdb_test "enable missing-debug-handler global" \
    347  1.1  christos 	"^2 missing debug handlers enabled"
    348  1.1  christos 
    349  1.1  christos     gdb_test "info missing-debug-handlers" \
    350  1.1  christos 	[multi_line \
    351  1.1  christos 	     "Progspace \[^\r\n\]+:" \
    352  1.1  christos 	     "  abc-def" \
    353  1.1  christos 	     "  baz- \\\[disabled\\\]" \
    354  1.1  christos 	     "Global:" \
    355  1.1  christos 	     "  -bar" \
    356  1.1  christos 	     "  Foo"]
    357  1.1  christos 
    358  1.1  christos     gdb_file_cmd $binfile
    359  1.1  christos     gdb_test "python print(handler_call_log)" \
    360  1.1  christos 	[string_to_regexp {['abc-def', '-bar', 'Foo']}]
    361  1.1  christos     gdb_test_no_output "python handler_call_log = \[\]" \
    362  1.1  christos 	"reset call log"
    363  1.1  christos }
    364  1.1  christos 
    365  1.1  christos # Add handler_obj to the global handler list, and configure it to
    366  1.1  christos # return False.  We should call all of the program space specific
    367  1.1  christos # handlers (which return None), and then call handler_obj from the
    368  1.1  christos # global list, which returns False, at which point we shouldn't call
    369  1.1  christos # anyone else.
    370  1.1  christos with_test_prefix "return False handler in progspace list" {
    371  1.1  christos     gdb_test "enable missing-debug-handler progspace" \
    372  1.1  christos 	"^1 missing debug handler enabled"
    373  1.1  christos 
    374  1.1  christos     gdb_test_no_output \
    375  1.1  christos 	"python gdb.missing_debug.register_handler(None, handler_obj)" \
    376  1.1  christos 	"register the initial handler"
    377  1.1  christos 
    378  1.1  christos     gdb_test "info missing-debug-handlers" \
    379  1.1  christos 	[multi_line \
    380  1.1  christos 	     "Progspace \[^\r\n\]+:" \
    381  1.1  christos 	     "  abc-def" \
    382  1.1  christos 	     "  baz-" \
    383  1.1  christos 	     "Global:" \
    384  1.1  christos 	     "  handler" \
    385  1.1  christos 	     "  -bar" \
    386  1.1  christos 	     "  Foo"]
    387  1.1  christos 
    388  1.1  christos     gdb_test_no_output "python handler_obj.set_mode(Mode.RETURN_FALSE)" \
    389  1.1  christos 	"confirgure handler"
    390  1.1  christos 
    391  1.1  christos     gdb_file_cmd $binfile
    392  1.1  christos     gdb_test "python print(handler_call_log)" \
    393  1.1  christos 	[string_to_regexp {['abc-def', 'baz-', 'handler']}]
    394  1.1  christos     gdb_test_no_output "python handler_call_log = \[\]" \
    395  1.1  christos 	"reset call log"
    396  1.1  christos }
    397  1.1  christos 
    398  1.1  christos # Now add handler_obj to the current program space's handler list.  We
    399  1.1  christos # use the same handler object here, that's fine.  We should only see a
    400  1.1  christos # call to the first handler object in the call log.
    401  1.1  christos with_test_prefix "return False handler in global list" {
    402  1.1  christos     gdb_test_no_output \
    403  1.1  christos 	"python gdb.missing_debug.register_handler(pspace, handler_obj)" \
    404  1.1  christos 	"register the initial handler"
    405  1.1  christos 
    406  1.1  christos     gdb_test "info missing-debug-handlers" \
    407  1.1  christos 	[multi_line \
    408  1.1  christos 	     "Progspace \[^\r\n\]+:" \
    409  1.1  christos 	     "  handler" \
    410  1.1  christos 	     "  abc-def" \
    411  1.1  christos 	     "  baz-" \
    412  1.1  christos 	     "Global:" \
    413  1.1  christos 	     "  handler" \
    414  1.1  christos 	     "  -bar" \
    415  1.1  christos 	     "  Foo"]
    416  1.1  christos 
    417  1.1  christos     gdb_file_cmd $binfile
    418  1.1  christos     gdb_test "python print(handler_call_log)" \
    419  1.1  christos 	[string_to_regexp {['handler']}]
    420  1.1  christos     gdb_test_no_output "python handler_call_log = \[\]" \
    421  1.1  christos 	"reset call log"
    422  1.1  christos }
    423  1.1  christos 
    424  1.1  christos with_test_prefix "check handler replacement" {
    425  1.1  christos     # First, check we can have the same name appear in both program
    426  1.1  christos     # space and global lists without giving an error.
    427  1.1  christos     gdb_test_no_output "python register(\"Foo\", pspace)"
    428  1.1  christos 
    429  1.1  christos     gdb_test "info missing-debug-handlers" \
    430  1.1  christos 	[multi_line \
    431  1.1  christos 	     "Progspace \[^\r\n\]+:" \
    432  1.1  christos 	     "  Foo" \
    433  1.1  christos 	     "  handler" \
    434  1.1  christos 	     "  abc-def" \
    435  1.1  christos 	     "  baz-" \
    436  1.1  christos 	     "Global:" \
    437  1.1  christos 	     "  handler" \
    438  1.1  christos 	     "  -bar" \
    439  1.1  christos 	     "  Foo"]
    440  1.1  christos 
    441  1.1  christos     # Now check that we get an error if we try to add a handler with
    442  1.1  christos     # the same name.
    443  1.1  christos     gdb_test "python gdb.missing_debug.register_handler(pspace, log_handler(\"Foo\"))" \
    444  1.1  christos 	[multi_line \
    445  1.1  christos 	     "RuntimeError.*: Handler Foo already exists\\." \
    446  1.1  christos 	     "Error occurred in Python.*"]
    447  1.1  christos 
    448  1.1  christos     gdb_test "python gdb.missing_debug.register_handler(handler=log_handler(\"Foo\"), locus=pspace)" \
    449  1.1  christos 	[multi_line \
    450  1.1  christos 	     "RuntimeError.*: Handler Foo already exists\\." \
    451  1.1  christos 	     "Error occurred in Python.*"]
    452  1.1  christos 
    453  1.1  christos     # And now try again, but this time with 'replace=True', we
    454  1.1  christos     # shouldn't get an error in this case.
    455  1.1  christos     gdb_test_no_output \
    456  1.1  christos 	"python gdb.missing_debug.register_handler(pspace, log_handler(\"Foo\"), replace=True)"
    457  1.1  christos 
    458  1.1  christos     gdb_test_no_output \
    459  1.1  christos 	"python gdb.missing_debug.register_handler(handler=log_handler(\"Foo\"), locus=None, replace=True)"
    460  1.1  christos 
    461  1.1  christos     # Now disable a handler and check we still need to use 'replace=True'.
    462  1.1  christos     gdb_test "disable missing-debug-handler progspace Foo" \
    463  1.1  christos 	"^1 missing debug handler disabled"
    464  1.1  christos 
    465  1.1  christos     gdb_test "python gdb.missing_debug.register_handler(pspace, log_handler(\"Foo\"))" \
    466  1.1  christos 	[multi_line \
    467  1.1  christos 	     "RuntimeError.*: Handler Foo already exists\\." \
    468  1.1  christos 	     "Error occurred in Python.*"] \
    469  1.1  christos 	"still get an error when handler is disabled"
    470  1.1  christos 
    471  1.1  christos     gdb_test_no_output \
    472  1.1  christos 	"python gdb.missing_debug.register_handler(pspace, log_handler(\"Foo\"), replace=True)" \
    473  1.1  christos 	"can replace a disabled handler"
    474  1.1  christos }
    475