summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2013-12-24 08:19:16 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2013-12-24 09:14:12 +1000
commitfd3118ea1ac1442e5bf960e3d577aacc08aa3d63 (patch)
treefdb7f5b533cda98203c3c52743b2593920c807b2
parent49f0b9300e394889e2dd3964fe29e493265f1683 (diff)
downloadlibevdev-fd3118ea1ac1442e5bf960e3d577aacc08aa3d63.tar.gz
test: detect if we're running inside gdb and disable forking
The Check test framework forks by default which is annoying when running gdb. Try to detect whether we're inside gdb by ptracing ourselves. If that works, we're not inside a debugger. If it doesn't, then assume we're inside a debugger and set CK_FORK to "no". Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--libevdev/libevdev.h5
-rw-r--r--test/test-main.c37
2 files changed, 40 insertions, 2 deletions
diff --git a/libevdev/libevdev.h b/libevdev/libevdev.h
index 37ca2f4..f5ceda0 100644
--- a/libevdev/libevdev.h
+++ b/libevdev/libevdev.h
@@ -177,8 +177,9 @@ extern "C" {
* git grep "suite_create"
* git grep "tcase_create"
*
- * By default, check forks, making debugging harder. Run gdb as below to avoid
- * forking.
+ * By default, Check forks, making debugging harder. The test suite tries to detect
+ * if it is running inside gdb and disable forking. If that doesn't work for
+ * some reason, run gdb as below to avoid forking.
*
* sudo CK_FORK=no CK_RUN_TEST="test case name" gdb ./test/test-libevdev
*
diff --git a/test/test-main.c b/test/test-main.c
index 73d79c9..91128c3 100644
--- a/test/test-main.c
+++ b/test/test-main.c
@@ -22,6 +22,10 @@
#include <config.h>
#include <check.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ptrace.h>
+#include <sys/wait.h>
extern Suite *event_name_suite(void);
extern Suite *event_code_suite(void);
@@ -31,9 +35,42 @@ extern Suite *libevdev_has_event_test(void);
extern Suite *libevdev_events(void);
extern Suite *uinput_suite(void);
+static int
+is_debugger_attached(void)
+{
+ int status;
+ int rc;
+ int pid = fork();
+
+ if (pid == -1)
+ return 0;
+
+ if (pid == 0) {
+ int ppid = getppid();
+ if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) == 0) {
+ waitpid(ppid, NULL, 0);
+ ptrace(PTRACE_CONT, NULL, NULL);
+ ptrace(PTRACE_DETACH, ppid, NULL, NULL);
+ rc = 0;
+ } else
+ rc = 1;
+ _exit(rc);
+ } else {
+ waitpid(pid, &status, 0);
+ rc = WEXITSTATUS(status);
+ }
+
+ return rc;
+}
+
+
int main(int argc, char **argv)
{
int failed;
+
+ if (is_debugger_attached())
+ setenv("CK_FORK", "no", 0);
+
Suite *s = libevdev_has_event_test();
SRunner *sr = srunner_create(s);
srunner_add_suite(sr, libevdev_events());