[2/2] testsuite, mi: prevent buffer overflow in get_mi_thread_list

Message ID 20240227180414.3366314-2-tankut.baris.aktemur@intel.com
State New
Headers
Series [1/2] testsuite, mi: fix indentation in get_mi_thread_list |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm fail Testing failed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 fail Testing failed

Commit Message

Aktemur, Tankut Baris Feb. 27, 2024, 6:04 p.m. UTC
  If there is a large number of threads in the input program, the
expect buffer in `get_mi_thread_list` would become full.  Prevent this
by consuming the buffer in small pieces.
---
 gdb/testsuite/lib/mi-support.exp | 51 +++++++++++++++++---------------
 1 file changed, 27 insertions(+), 24 deletions(-)
  

Patch

diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index 33a3a71b396..bbc8bf0a297 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -1953,39 +1953,42 @@  proc mi_run_inline_test { testcase } {
 }
 
 proc get_mi_thread_list {name} {
-    global expect_out
+    global expect_out decimal mi_gdb_prompt
 
     # MI will return a list of thread ids:
     #
     # -thread-list-ids
-    # ^done,thread-ids=[thread-id="1",thread-id="2",...],number-of-threads="N"
+    # ^done,thread-ids={thread-id="1",thread-id="2",...},number-of-threads="N"
     # (gdb)
-    mi_gdb_test "-thread-list-ids" \
-	{.*\^done,thread-ids={(thread-id="[0-9]+"(,)?)+},current-thread-id="[0-9]+",number-of-threads="[0-9]+"} \
-	"-thread_list_ids ($name)"
-
-    set output {}
-    if {[info exists expect_out(buffer)]} {
-	set output $expect_out(buffer)
-    }
-
+    #
+    # In case there are too many threads, the expect buffer would
+    # become full.  Process the buffer contents in small chunks.
     set thread_list {}
-    if {![regexp {thread-ids=\{(thread-id="[0-9]+"(,)?)*\}} $output threads]} {
-	fail "finding threads in MI output ($name)"
-    } else {
-	pass "finding threads in MI output ($name)"
-
-	# Make list of console threads
-	set start [expr {[string first \{ $threads] + 1}]
-	set end   [expr {[string first \} $threads] - 1}]
-	set threads [string range $threads $start $end]
-	foreach thread [split $threads ,] {
-	    if {[scan $thread {thread-id="%d"} num]} {
-		lappend thread_list $num
-	    }
+    set num_threads "unknown"
+    gdb_test_multiple "-thread-list-ids" "$name: get mi thread list" {
+	-re "done,thread-ids=\{" {
+	    exp_continue
+	}
+	-re "^thread-id=\"($decimal)\"(,|\})" {
+	    set num $expect_out(1,string)
+	    lappend thread_list $num
+	    exp_continue
+	}
+	-re "^,current-thread-id=\"$decimal\"" {
+	    exp_continue
+	}
+	-re "^,number-of-threads=\"($decimal)\"" {
+	    set num_threads $expect_out(1,string)
+	    exp_continue
+	}
+	-re "^\r\n$mi_gdb_prompt" {
+	    pass $gdb_test_name
 	}
     }
 
+    gdb_assert {[llength $thread_list] == $num_threads} \
+	"$name: found thread ids in MI output"
+
     return $thread_list
 }