]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
testsuite: Introduce gdb_watchdog (avoid unistd.h/alarm)
authorPedro Alves <pedro@palves.net>
Fri, 8 Aug 2025 22:50:04 +0000 (23:50 +0100)
committerPedro Alves <pedro@palves.net>
Fri, 22 Aug 2025 18:45:49 +0000 (19:45 +0100)
There are a good number of testcases in the testsuite that use alarm()
as a watchdog that aborts the test if something goes wrong.

alarm()/SIG_ALRM do not exist on (native) Windows, so those tests fail
to compile there.

For example, testing with x86_64-w64-mingw32-gcc, we see:

 Running /c/rocgdb/src/gdb/testsuite/gdb.base/attach.exp ...
 gdb compile failed, C:/rocgdb/src/gdb/testsuite/gdb.base/attach.c: In function 'main':
 C:/rocgdb/src/gdb/testsuite/gdb.base/attach.c:17:3: error: implicit declaration of function 'alarm' [-Wimplicit-function-declaration]
    17 |   alarm (60);
       |   ^~~~~

While testing with a clang configured to default to
x86_64-pc-windows-msvc, which uses the C/C++ runtime headers from
Visual Studio and has no unistd.h, we get:

 Running /c/rocgdb/src/gdb/testsuite/gdb.base/attach.exp ...
 gdb compile failed, C:/rocgdb/src/gdb/testsuite/gdb.base/attach.c:8:10: fatal error: 'unistd.h' file not found
     8 | #include <unistd.h>
       |          ^~~~~~~~~~

Handle this by adding a new testsuite/lib/gdb_watchdog.h header that
defines a new gdb_watchdog function, which wraps alarm on Unix-like
systems, and uses a timer on Windows.

This patch adjusts gdb.base/attach.c as example of usage.  Testing
gdb.base/attach.exp with clang/x86_64-pc-windows-msvc required a
related portability tweak to can_spawn_for_attach, to not rely on
unistd.h on Windows.

gdb.rocm/mi-attach.cpp is another example adjusted, one which always
runs with clang configured as x86_64-pc-windows-msvc on Windows (via
hipcc).

Approved-by: Kevin Buettner <kevinb@redhat.com>
Change-Id: I3b07bcb60de039d34888ef3494a5000de4471951

gdb/testsuite/gdb.base/attach.c
gdb/testsuite/gdb.rocm/mi-attach.cpp
gdb/testsuite/lib/gdb.exp
gdb/testsuite/lib/gdb_watchdog.h [new file with mode: 0644]

index b3c5498401271b08ec7ba7afe210aad1df5aeaba..5133dd07e556e5f3ddf31d30d76078664bb517c1 100644 (file)
@@ -5,7 +5,7 @@
    exit unless/until gdb sets the variable to non-zero.)
    */
 #include <stdio.h>
-#include <unistd.h>
+#include "gdb_watchdog.h"
 
 int  bidule = 0;
 volatile int  should_exit = 0;
@@ -14,7 +14,7 @@ int main ()
 {
   int  local_i = 0;
 
-  alarm (60);
+  gdb_watchdog (60);
 
   while (! should_exit)
     {
index da7659dc5664d828d92aa0248c33dd143ae93a71..441d460146a1f7df05f666abf3540b6e7f100cd1 100644 (file)
@@ -15,8 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#include <unistd.h>
 #include <hip/hip_runtime.h>
+#include "gdb_watchdog.h"
 
 __global__ void
 kern ()
@@ -30,7 +30,7 @@ main ()
 {
   /* This program will run outside of GDB, make sure that if anything goes
      wrong it eventually gets killed.  */
-  alarm (30);
+  gdb_watchdog (30);
 
   kern<<<1, 1>>> ();
   return hipDeviceSynchronize () != hipSuccess;
index 0361f10b9a616db3799221ad8054db7ca5526391..d989314c28d76e4e7a838d2ff4127e69f73699fa 100644 (file)
@@ -6849,7 +6849,20 @@ gdb_caching_proc can_spawn_for_attach {} {
 
     set me "can_spawn_for_attach"
     set src {
-       #include <unistd.h>
+       #ifdef _WIN32
+       # include <windows.h>
+       #else
+       # include <unistd.h>
+       #endif
+
+       #ifdef _WIN32
+       unsigned
+       sleep (unsigned seconds)
+       {
+           Sleep (seconds * 1000);
+           return 0;
+       }
+       #endif
 
        int
        main (void)
diff --git a/gdb/testsuite/lib/gdb_watchdog.h b/gdb/testsuite/lib/gdb_watchdog.h
new file mode 100644 (file)
index 0000000..15d63e7
--- /dev/null
@@ -0,0 +1,75 @@
+/* This file is part of GDB, the GNU debugger.
+
+   Copyright 2025 Free Software Foundation, Inc.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+/* Set a watchdog that aborts the testcase after a timeout.  */
+
+#ifndef GDB_WATCHDOG_H
+#define GDB_WATCHDOG_H
+
+/* Forward declaration to make sure the definitions have the right
+   prototype, at least in C.  */
+static void gdb_watchdog (unsigned int seconds);
+
+static const char _gdb_watchdog_msg[]
+  = "gdb_watchdog: timeout expired - aborting test\n";
+
+#ifdef _WIN32
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static VOID CALLBACK
+_gdb_watchdog_timer_routine (PVOID lpParam, BOOLEAN TimerOrWaitFired)
+{
+  fputs (_gdb_watchdog_msg, stderr);
+  abort ();
+}
+
+static void
+gdb_watchdog (unsigned int seconds)
+{
+  HANDLE timer;
+
+  if (!CreateTimerQueueTimer (&timer, NULL,
+                             _gdb_watchdog_timer_routine, NULL,
+                             seconds * 1000, 0, 0))
+    abort ();
+}
+
+#else /* POSIX systems */
+
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+
+static void
+_gdb_sigalrm_handler (int signo)
+{
+  write (2, _gdb_watchdog_msg, sizeof (_gdb_watchdog_msg) - 1);
+  abort ();
+}
+
+static void
+gdb_watchdog (unsigned int seconds)
+{
+  signal (SIGALRM, _gdb_sigalrm_handler);
+  alarm (seconds);
+}
+
+#endif
+
+#endif /* GDB_WATCHDOG_H */