[binutils-gdb] GDB/testsuite: Fix schedlock.exp crash due to empty $after_args

"Maciej W. Rozycki via Gdb-cvs" <[email protected]>
Newsgroups gmane.comp.gdb.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=39f66e71b609f8f7b53ea4d49fa31b7db6996904

commit 39f66e71b609f8f7b53ea4d49fa31b7db6996904
Author: Maciej W. Rozycki <[email protected]>
Date:   Tue Apr 28 22:54:56 2026 +0100

    GDB/testsuite: Fix schedlock.exp crash due to empty $after_args
    
    Prevent gdb.threads/schedlock.exp from crashing due to a premature exit
    of the debuggee causing an attempt to use a nil value as an arithmetic
    operand:
    
    [...]
    (gdb) FAIL: gdb.threads/schedlock.exp: schedlock=off: cmd=next: call_function=0: next to increment, 9
    bt
    The current thread has terminated
    (gdb) FAIL: gdb.threads/schedlock.exp: schedlock=off: cmd=next: call_function=0: find current thread, after
    FAIL: gdb.threads/schedlock.exp: schedlock=off: cmd=next: call_function=0: next does not change thread (switched to thread )
    print args
    Cannot access memory at address 0x410ab0
    (gdb) FAIL: gdb.threads/schedlock.exp: schedlock=off: cmd=next: call_function=0: listed args, after
    ERROR: tcl error sourcing .../gdb/testsuite/gdb.threads/schedlock.exp.
    ERROR: can't use empty string as operand of "-"
        while executing
    "if {$cmd == "continue"
                        || [lindex $before_args $i] == [lindex $after_args $i] - 10} {
                        pass "$test"
                    } else {
                        fail "$test (wrong amo..."
        (procedure "check_result" line 31)
        invoked from within
    "check_result $cmd $curthread $before_args $locked"
        (procedure "test_step" line 26)
        invoked from within
    "test_step $schedlock "next" $call_function"
        ("uplevel" body line 2)
        invoked from within
    "uplevel 1 $body"
        invoked from within
    "with_test_prefix "call_function=$call_function" {
                        test_step $schedlock "next" $call_function
                    }"
        ("foreach" body line 2)
        invoked from within
    "foreach call_function {0 1} {
                    with_test_prefix "call_function=$call_function" {
                        test_step $schedlock "next" $call_function
                    }
                }"
        ("uplevel" body line 6)
        invoked from within
    "uplevel 1 $body"
        invoked from within
    "with_test_prefix "cmd=next" {
                # In GDB <= 7.9, with schedlock "step", "next" would
                # unlock threads when stepping over a function call.  Thi..."
        ("uplevel" body line 5)
        invoked from within
    "uplevel 1 $body"
        invoked from within
    "with_test_prefix "schedlock=$schedlock" {
            with_test_prefix "cmd=step" {
                test_step $schedlock "step" 0
            }
            with_test_prefix "cmd=next" {
                # I..."
        ("foreach" body line 2)
        invoked from within
    "foreach schedlock {"off" "step" "on"} {
        with_test_prefix "schedlock=$schedlock" {
            with_test_prefix "cmd=step" {
                test_step $schedlock "step" ..."
        (file ".../gdb/testsuite/gdb.threads/schedlock.exp" line 297)
        invoked from within
    "source .../gdb/testsuite/gdb.threads/schedlock.exp"
        ("uplevel" body line 1)
        invoked from within
    "uplevel #0 source .../gdb/testsuite/gdb.threads/schedlock.exp"
        invoked from within
    "catch "uplevel #0 source $test_file_name""
    Remote debugging from host xx.xx.xx.xx, port 56596
    monitor exit
    (gdb) Killing process(es): 22658
    testcase .../gdb/testsuite/gdb.threads/schedlock.exp completed in 32 seconds
    
    Here `print args' has failed to produce output matching the pattern
    expected by `get_args' and consequently an empty value has been assigned
    to $after_args.  Subsequently a calculation is attempted on an element
    of said value treated as a list: `[lindex $after_args $i] - 10' and that
    has caused the crash because the resulting minuend is nil.
    
    There are various expressions $after_args and other variables set from
    the result of `get_args' are used in, however the majority are equality
    operations, which succeed producing a result even where a nil operand is
    involved.  Given that this is a test failure scenario anyway follow the
    path of least resistance, ignore the other expressions and just prevent
    the crash from triggering here by checking for an attempt to retrieve an
    inexistent element of $after_args for this calculation, and report it as
    a test failure outright letting the script proceed:
    
    [...]
    (gdb) FAIL: gdb.threads/schedlock.exp: schedlock=off: cmd=next: call_function=0: next to increment, 9
    bt
    The current thread has terminated
    (gdb) FAIL: gdb.threads/schedlock.exp: schedlock=off: cmd=next: call_function=0: find current thread, after
    FAIL: gdb.threads/schedlock.exp: schedlock=off: cmd=next: call_function=0: next does not change thread (switched to thread )
    print args
    Cannot access memory at address 0x410ab0
    (gdb) FAIL: gdb.threads/schedlock.exp: schedlock=off: cmd=next: call_function=0: listed args, after
    FAIL: gdb.threads/schedlock.exp: schedlock=off: cmd=next: call_function=0: current thread advanced - unlocked (no arg #1)
    PASS: gdb.threads/schedlock.exp: schedlock=off: cmd=next: call_function=0: other threads ran - unlocked
    set scheduler-locking off
    (gdb) PASS: gdb.threads/schedlock.exp: schedlock=off: cmd=next: call_function=1: set scheduler-locking off
    [...]
    
    Approved-by: Kevin Buettner <[email protected]>

Diff:
---
 gdb/testsuite/gdb.threads/schedlock.exp | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/gdb/testsuite/gdb.threads/schedlock.exp b/gdb/testsuite/gdb.threads/schedlock.exp
index a6c453c59c2..eeca3f8fd0f 100644
--- a/gdb/testsuite/gdb.threads/schedlock.exp
+++ b/gdb/testsuite/gdb.threads/schedlock.exp
@@ -232,8 +232,12 @@ proc check_result { cmd before_thread before_args locked } {
 	    }
 	} else {
 	    if {$i == $before_thread} {
-		if {$cmd == "continue"
-		    || [lindex $before_args $i] == [lindex $after_args $i] - 10} {
+		if {$cmd == "continue"} {
+		    pass "$test"
+		} elseif {[llength $after_args] <= $i} {
+		    fail "$test (no arg #$i)"
+		} elseif {[lindex $before_args $i] \
+			  == [lindex $after_args $i] - 10} {
 		    pass "$test"
 		} else {
 		    fail "$test (wrong amount)"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.