Home | History | Annotate | Line # | Download | only in gdb.python
      1 # Copyright (C) 2017-2024 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 # Please email any bugs, comments, and/or additions to this file to:
     17 # bug-gdb (at) gnu.org
     18 
     19 # This file verifies that methods Inferior.thread_from_handle
     20 # and InferiorThread.handle work as expected.
     21 
     22 load_lib gdb-python.exp
     23 
     24 require allow_python_tests
     25 
     26 standard_testfile
     27 
     28 if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable debug] != "" } {
     29     return -1
     30 }
     31 
     32 clean_restart ${binfile}
     33 
     34 runto_main
     35 
     36 gdb_test "break after_mc_barrier" \
     37     "Breakpoint 2 at .*: file .*${srcfile}, line .*" \
     38          "breakpoint on after_mc_barrier"
     39 
     40 gdb_test "break do_something" \
     41     "Breakpoint 3 at .*: file .*${srcfile}, line .*" \
     42          "breakpoint on do_something"
     43 
     44 gdb_test "continue" \
     45 	"Breakpoint 2, after_mc_barrier .*" \
     46 	"run to after_mc_barrier"
     47 
     48 gdb_test_no_output "del 2" "delete after_mc_barrier breakpoint"
     49 
     50 gdb_test "continue" \
     51 	"Breakpoint 3, do_something .*" \
     52 	"run to do_something"
     53 
     54 # The test case has been constructed so that the current thread,
     55 # indicated by '*' in the "info threads" output, should be stopped in
     56 # do_something() with a value of n which is the same as the number
     57 # reported in the "Id" column.  If it's not, then something went wrong
     58 # with the start up sequence which should cause the main thread to be
     59 # thread 1, the first child thread to be thread 2, and the second
     60 # child thread to be thread 3.
     61 #
     62 # Note that \1 in the RE below is a backreference to the thread id
     63 # reported in the "Id" column.
     64 
     65 gdb_test "info threads"  \
     66 	[format {.*[\r\n]+\* +([0-9]+) +%s[^\r\n]* do_something \(n=\1\) at.*} $tdlabel_re]
     67 
     68 # Check for expected results when passing a valid thread handle to
     69 # thread_from_handle().
     70 
     71 gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('thrs\[0\]')).num)" \
     72 	"1" "print thread id for thrs\[0\]"
     73 
     74 gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('thrs\[1\]')).num)" \
     75 	"2" "print thread id for thrs\[1\]"
     76 
     77 gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('thrs\[2\]')).num)" \
     78 	"3" "print thread id for thrs\[2\]"
     79 
     80 # Objects which are of the correct size, but which are bogus thread
     81 # handles should return None.  For the first test (using thrs[3]), we
     82 # use 0.  For the second (thrs[4]), we use an unlikely bit pattern.
     83 
     84 gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('thrs\[3\]')))" \
     85 	"None" "print thread for bogus handle thrs\[3\]"
     86 
     87 gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('thrs\[4\]')))" \
     88 	"None" "print thread for bogus handle thrs\[4\]"
     89 
     90 # We should see an exception when passing an object of the wrong type.
     91 
     92 gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.lookup_symbol('main')))" \
     93          ".*TypeError.*: Argument 'handle' must be a thread handle object.*" \
     94 	 "TypeError when passing a symbol object to thread_from_handle"
     95 
     96 # We should see an exception when passing too large of an object.
     97 
     98 gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('thrs')))" \
     99          ".*Thread handle size mismatch.*" \
    100 	 "Pass overly large object to thread_from_handle"
    101 
    102 # We should see an exception when passing too small of an object.
    103 
    104 gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('\"S\"')))" \
    105          ".*Thread handle size mismatch.*" \
    106 	 "Pass too small of an object to thread_from_handle"
    107 
    108 # Test the thread_handle method
    109 
    110 gdb_py_test_silent_cmd "python tp=gdb.lookup_type('pthread_t')" \
    111 		       "Get pthread_t type" 0
    112 gdb_py_test_silent_cmd "python inf=gdb.selected_inferior()" "Get inferior" 0
    113 
    114 foreach thrN {0 1 2} {
    115     with_test_prefix "thread $thrN" {
    116 
    117 	gdb_py_test_silent_cmd \
    118 	    "python hand = gdb.parse_and_eval('thrs\[$thrN\]')" \
    119 	    "fetch thread handle from inferior" \
    120 	    1
    121 
    122 	gdb_py_test_silent_cmd \
    123 	    "python hand_bytes = inf.thread_from_handle(hand).handle()" \
    124 	    "fetch thread handle from thread" \
    125 	    1
    126 
    127 
    128 	# It'd be nice to be able to use this comparison expression:
    129 	#
    130 	#    hand == hand_bytes
    131 	#
    132 	# But this won't work because hand is a gdb.Value and hand_bytes
    133 	# is a Python bytes object.  Therefore, we convert the bytes
    134 	# object into a gdb.value by calling the two argument form of
    135 	# its constructor.
    136 
    137         gdb_test "python print(gdb.Value(hand_bytes, tp) == hand)" \
    138 	         "True" \
    139 	         "verify that handles are the same"
    140     }
    141 }
    142