소스 검색

Have the test loader launch gdb upon signaled exit.

Ludovic Courtès 13 년 전
부모
커밋
0963375348
2개의 변경된 파일93개의 추가작업 그리고 2개의 파일을 삭제
  1. 12 0
      configure.ac
  2. 81 2
      tests/loader.c

+ 12 - 0
configure.ac

@@ -1293,6 +1293,18 @@ AM_CONDITIONAL([STARPU_USE_SOCL], [test "x$build_socl" = "xyes"])
 
 ###############################################################################
 #                                                                             #
+#                                 Debugging                                   #
+#                                                                             #
+###############################################################################
+
+AC_PATH_PROG([GDB], [gdb], [not-found])
+if test "x$GDB" != "xnot-found"; then
+   AC_DEFINE_UNQUOTED([STARPU_GDB_PATH], ["$GDB"],
+     [Path to the GNU debugger.])
+fi
+
+###############################################################################
+#                                                                             #
 #                                  Examples                                   #
 #                                                                             #
 ###############################################################################

+ 81 - 2
tests/loader.c

@@ -14,6 +14,10 @@
  * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  */
 
+#include <common/config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/wait.h>
 #include <sys/resource.h>
 #include <unistd.h>
@@ -22,14 +26,88 @@
 #include <signal.h>
 #include <string.h>
 
-#include <common/config.h>
-
 #define  DEFAULT_TIMEOUT       600
 #define  AUTOTEST_SKIPPED_TEST 77
 
 static pid_t child_pid = 0;
 static int   timeout;
 
+static void launch_gdb(const char *exe)
+{
+#ifdef STARPU_GDB_PATH
+# define CORE_FILE "core"
+# define GDB_COMMAND "thread apply all bt full"
+	int err;
+	pid_t pid;
+	struct stat st;
+	const char *top_builddir;
+	char *gdb;
+
+	err = stat(CORE_FILE, &st);
+	if (err != 0)
+	{
+		fprintf(stderr, "while looking for core file of %s: %s: %m\n",
+			exe, CORE_FILE);
+		return;
+	}
+
+	if (!(st.st_mode & S_IFREG))
+	{
+		fprintf(stderr, CORE_FILE ": not a regular file\n");
+		return;
+	}
+
+	top_builddir = getenv("top_builddir");
+
+	pid = fork();
+	switch (pid)
+	{
+	case 0:					  /* kid */
+		if (top_builddir != NULL)
+		{
+			/* Run gdb with Libtool.  */
+			gdb = alloca(strlen(top_builddir)
+				     + sizeof("libtool") + 1);
+			strcpy(gdb, top_builddir);
+			strcat(gdb, "/libtool");
+			err = execl(gdb, "gdb", "--mode=execute",
+				    STARPU_GDB_PATH, "--batch",
+				    "-ex", GDB_COMMAND,
+				    exe, CORE_FILE, NULL);
+		}
+		else
+		{
+			/* Run gdb directly  */
+			gdb = STARPU_GDB_PATH;
+			err = execl(gdb, "gdb", "--batch", "-ex", GDB_COMMAND,
+				    exe, CORE_FILE, NULL);
+		}
+		if (err != 0)
+		{
+			fprintf(stderr, "while launching `%s': %m\n", gdb);
+			exit(EXIT_FAILURE);
+		}
+		exit(EXIT_SUCCESS);
+		break;
+
+	case -1:
+		fprintf(stderr, "fork: %m\n");
+		return;
+
+	default:				  /* parent */
+		{
+			int status;
+			err = waitpid(pid, &status, 0);
+			if (err != 0)
+				fprintf(stderr, "while waiting for gdb "
+					"process %d: %m\n", pid);
+		}
+	}
+# undef GDB_COMMAND
+# undef CORE_FILE
+#endif	/* STARPU_GDB_PATH */
+}
+
 static void test_cleaner(int sig)
 {
 	pid_t child_gid;
@@ -164,6 +242,7 @@ int main(int argc, char *argv[])
 		{
 			fprintf(stderr, "[error] `%s' killed with signal %d; test marked as failed\n",
 				test_name, WTERMSIG(child_exit_status));
+			launch_gdb(test_name);
 			return EXIT_FAILURE;
 		}
 		else