# Copyright (C) 2019-2024 Free Software Foundation, Inc. # Copyright (C) 2019-2024 Advanced Micro Devices, Inc. All rights reserved. # This file is part of GDB. # 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 . load_lib rocm.exp require allow_hip_tests standard_testfile .cpp if {[prepare_for_testing "failed to prepare ${testfile}" $testfile $srcfile {debug hip}]} { return -1 } with_rocm_gpu_lock { if ![runto_main] { fail "can't run to main" return -1 } set ws "\[ \t\]" gdb_test "info queues" "No queues are currently active\\." "info queues, no queues" # Set breakpoint in device code. gdb_breakpoint "bit_extract_kernel" "allow-pending" gdb_continue_to_breakpoint "bit_extract_kernel" #Test0 # Check that dbgapi is properly configured to display "info agents". # # In case dbgapi is not properly configured to find the device name database it # will issue a warning and generate a fallback name in the form # "Device vvvv:dddd" or "Device vvvv:dddd.rr". # # It is however possible to have a name matching "Device vvvv:dddd[.rr]" if # dbgapi is properly configured, but the device is not registered in the # database. In such situation, a hard fail would be erroneous. As a # misconfiguration of dbgapi is not really a GDB error, issue an XFAIL if # either a warning is issued or a device has a fallback name as both indicate # an environment problem. set seen_error 0 gdb_test_multiple "info agents" "dbgapi properly configured" { -re "amd-dbgapi: warning:" { set seen_error 1 exp_continue } -re "Device \[0-9a-zA-Z\]\{4\}:\[0-9a-zA-Z\]\{4\}(\\.\[0-9a-zA-Z\]\{2\})?${ws}" { set seen_error 1 exp_continue } -re -wrap "" { if {$seen_error == 1} { setup_xfail "*-*-*" fail $gdb_test_name } else { pass $gdb_test_name } } } #Test1 # Check "info agents". # vega10 sample output "1 A (GPUID 39113) vega10 224 2240 44:00.0" # vega20 sample output "1 A (GPUID 45151) vega20 240 2400 0a:00.0" gdb_test_sequence "info agents" "info agents" { {\s+Id\s+State\s+Target Id\s+Architecture\s+Device Name\s+Cores\s+Threads\s+Location} {\d+\s+[AU]\s+AMDGPU Agent \([^\)]*\)\s+\w+\s+[^\r\n]+\s+\d+\s+\d+\s+\w+:\w+:\d+\.\d} } #Test2 #Check info threads #sample output #* 5 AMDGPU Wave 1:1:1:1 (0,0,0)/0 "bit_extract_kernel" bit_extract_kernel () at bit_extract.cpp:38 # 6 AMDGPU Wave 1:1:1:2 (0,0,0)/1 "bit_extract_kernel" __hip_get_block_dim_x () gdb_test_sequence "info threads" "info threads" { {Id\s+Target\s+Id\s+Frame} {\d+\s+AMDGPU\sWave\s\d+\:\d+\:\d+\:\d+\s\(\d+,\d+,\d+\)/\d+} } #Test3 #Show architecture info while debugging in device code #Sample output "The target architecture is set automatically (currently amdgcn:gfx906)" gdb_test "show architecture" \ {The target architecture is set to "auto" \(currently "amdgcn:gfx\w+"\)\.} #Test4 gdb_test_sequence "show convenience" "show convenience" { {\$_thread = \d+} {\$_wave_id = \"\(\d+,\d+,\d+\)/\d+\"} } #Test6 #info break #sample output #Num Type Disp Enb Address What #1 breakpoint keep y 0x0000000000400d49 in main(int, char**) at bit_extract.cpp:54 # breakpoint already hit 1 time #2 breakpoint keep y 0x00007ffbdc2012dc in bit_extract_kernel() at bit_extract.cpp:38 # breakpoint already hit 1 time gdb_test_sequence "info break" "info break" { {Num\s+Type\s+Disp\sEnb Address\s+What} {\d+\s+breakpoint\s+keep\s+y} {breakpoint already hit\s\d+\stime} } #Test7 #info inferiors # Num Description Executable #* 1 process 34544 /home/amd/rohit/samples/0_Intro/bit_extract/bit_extrac gdb_test_sequence "info inferiors" "info inferiors" { {Num\s+Description\s+Connection\s+Executable} {\*\s\d+\s+process\s+\d+} } # Check that "info queues" gives us a non-empty output. set seen_header 0 set queue_ids [list] # Contains the per-queue information line (including the leading `*` for the # queue the current wave belongs to). set queue_info_lines [list] # A list of agent id's for each queue entry. set agent_ids [list] # A list of OS queue id's for each queue entry. set os_ids [list] set table_header_regex "${ws}+Target${ws}+Id${ws}+Type${ws}+Read${ws}+Write${ws}+Size${ws}+Address${ws}*" gdb_test_multiple "info queues" "info queues with queues" { -re $table_header_regex { set seen_header 1 exp_continue } -re "\r\n(\\*?${ws}*(\\d+)${ws}+AMDGPU Queue${ws}+(\\d+):\\d+ \\(QID (\\d+)\\)${ws}+(HSA|PM4|DMA|XGMI|Unknown)${ws}+(\\d+${ws}+)?(\\d+${ws}+)?\\d+${ws}+${::hex}${ws}*(?=\r\n))" { lappend queue_ids $expect_out(2,string) lappend agent_ids $expect_out(3,string) lappend os_ids $expect_out(4,string) lappend queue_info_lines $expect_out(1,string) exp_continue } -re -wrap "" { gdb_assert {[llength $queue_ids] > 0 && $seen_header} $gdb_test_name } } # Check that "info queues" lists queues in order. This ensures that # we captured all the queues. set ok 1 for {set i 0} {$i < [llength $queue_ids]} {incr i} { set qnum [lindex $queue_ids $i] if {$qnum != [expr {$i + 1}]} { verbose -log "Mismatch: entry $i has queue number $qnum, expected [expr {$i+1}]" set ok 0 } } gdb_assert $ok "queue numbers in expected order" # Check that we can get infos for queues individually. for { set i 0 } { $i < [llength $queue_ids] } { incr i } { gdb_test "info queue [lindex $queue_ids $i]" \ "$table_header_regex\r\n[string_to_regexp [lindex $queue_info_lines $i]]" \ "info queue, queue $i" } # Check the path where we provide an invalid queue id. # Pick the highest queue_id seen + 1. if {[llength $queue_ids] > 0} { # The highest is the last. set invalid_id [expr [llength $queue_ids] + 1] gdb_test "info queues $invalid_id" \ "No active queues match '$invalid_id'\\." \ "info queues, no match" # Test the "queue find [regexp]" command. # Invalid ID. gdb_test "queue find 1:$invalid_id" \ "No queues match '1:$invalid_id'" \ "queue find, no match" # Valid ID. # Fetch the index of the last entry. set index [expr [llength $queue_ids] - 1] # Fetch the queue, agent and OS ids. set valid_id [lindex $queue_ids $index] set agent_id [lindex $agent_ids $index] set os_id [lindex $os_ids $index] gdb_test "queue find $agent_id\[:\]$valid_id" \ "Queue $valid_id has Target Id 'AMDGPU Queue $agent_id:$valid_id \\(QID $os_id\\)'" \ "queue find, match" # Everything. The list is sorted per-inferior. set sequence [list] for {set i 0} {$i < [expr [llength $queue_ids]]} {incr i} { lappend sequence "Queue [lindex $queue_ids $i] has Target Id 'AMDGPU Queue [lindex $agent_ids $i]:[lindex $queue_ids $i] \\(QID [lindex $os_ids $i]\\)'" } gdb_test_sequence "queue find ." "" $sequence } gdb_test "clear bit_extract_kernel" "Deleted breakpoint.*" gdb_test "continue" {.+Inferior\s\d+.+\sexited\snormally.+} }