From: Tom de Vries Date: Fri, 28 Feb 2025 13:13:02 +0000 (+0100) Subject: [gdb/testsuite] Fix gdb.base/nostdlib.exp on aarch64 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8cdf110a115c971f3184bbd30f515fd2cd6f72ef;p=thirdparty%2Fbinutils-gdb.git [gdb/testsuite] Fix gdb.base/nostdlib.exp on aarch64 On aarch64-linux, in test-case gdb.base/nostdlib.exp I run into: ... (gdb) continue^M Continuing.^M warning: Temporarily disabling breakpoints for unloaded shared library \ "/lib/ld-linux-aarch64.so.1"^M ^M Breakpoint 2, _start () at nostdlib.c:20^M 20 {^M (gdb) FAIL: $exp: pie=pie: continue to marker ... This happens as follows: - the test-case sets a breakpoint on *_start, - the breakpoint resolves to *_start in the executable, - the executable is started, and the breakpoint resolves to *_start in the dynamic linker, - execution stops at *_start in the dynamic linker, - the test-case issues a continue, expecting to continue to the breakpoint on marker, - while continuing, the dynamic linker is reported as unloaded, - the breakpoint again resolves to *_start in the executable, - execution stops at *_start in the executable, and - the test-case concludes that it failed to "continue to marker". This doesn't happen on x86_64-linux. There, after the executable is started, the breakpoint again resolves to *_start in the exec. This is similar to what happens when printing _start. On aarch64-linux, we print the _start in the dynamic linker: ... $ gdb -q -batch outputs/gdb.base/nostdlib/nostdlib-pie \ -ex "b _start" \ -ex run \ -ex "print _start" \ -ex "info break" Breakpoint 1 at 0x2bc: file nostdlib.c, line 23. Breakpoint 1.2, _start () at ../sysdeps/aarch64/dl-start.S:22 22 ENTRY (_start) $1 = {void (void)} 0xfffff7fd6ac0 <_start> Num Type Disp Enb Address What 1 breakpoint keep y breakpoint already hit 1 time 1.1 y 0x0000aaaaaaaa02bc in _start at nostdlib.c:23 1.2 y 0x0000fffff7fd6ac0 in _start at dl-start.S:22 ... On x86_64-linux, we print the _start in the exec: ... Breakpoint 1 at 0x2c5: file nostdlib.c, line 23. Breakpoint 1.2, 0x00007ffff7fe4f00 in _start () from \ /lib64/ld-linux-x86-64.so.2 $1 = {void (void)} 0x5555555542c1 <_start> Num Type Disp Enb Address What 1 breakpoint keep y breakpoint already hit 1 time 1.1 y 0x00005555555542c5 in _start at nostdlib.c:23 1.2 y 0x00007ffff7fe4f00 <_start> ... The difference may be down to the availability of debug info for the _start in the dynamic linker. Finally, the described scenario on aarch64-linux is not deterministic. The behavior depends on the dynamic linker being reported as unloaded, which has been classified as a GLIBC bug, so that might get fixed. Ideally this test-case would stop at both *_start in the executable and the dynamic linker, but in absense of a way to specify this reliably (see PR32748), fix this by making this a temporary breakpoint, ensuring that the breakpoint will only trigger once. Approved-by: Kevin Buettner PR testsuite/32743 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32743 --- diff --git a/gdb/testsuite/gdb.base/nostdlib.exp b/gdb/testsuite/gdb.base/nostdlib.exp index 7c32e87ebdb..f595bab5a5b 100644 --- a/gdb/testsuite/gdb.base/nostdlib.exp +++ b/gdb/testsuite/gdb.base/nostdlib.exp @@ -52,13 +52,33 @@ foreach_with_prefix pie { "nopie" "pie" } { clean_restart $binfile gdb_breakpoint "*marker" - gdb_breakpoint "*_start" + + # Say we set a permanent breakpoint on *_start. When setting the + # breakpoint, it will resolve to _start in the exec. + # After starting to run, that may stay the same, and consequently + # execution will stop there. + # OTOH, after starting to run, that may change to *_start in the dynamic + # linker, and consequently execution will stop there. + # There's currently no way to enforce one or the other (PR32748). + # + # Say we run into a stop in *_start in the dynamic linker. Continuing + # from this situation, the dynamic linker is reported as unloaded, which + # makes the breakpoint resolve again to *_start in the exec, and + # consequently execution will stop there as well. + # + # However, we cannot rely on this behavior either. Reporting the dynamic + # linker as unloaded is a GLIBC bug, which may get fixed eventually. + # + # Instead of trying to cater for all these possibilities in a controlled + # fashion, make the breakpoint temporary, ensuring that there will just be + # one stop. + gdb_breakpoint "*_start" temporary gdb_run_cmd # Breakpoint 2, Stopped due to shared library event # _start () at ./gdb.base/nostdlib.c:20 - gdb_test "" {Breakpoint [0-9]+, .*_start .*} "stop at run" + gdb_test "" {Temporary breakpoint [0-9]+, .*_start .*} "stop at run" gdb_test "continue" {Breakpoint [0-9]+, marker .*} "continue to marker"