summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-07-24 11:41:59 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-07-24 11:50:00 +0100
commitbd3cf81e982d191715a68b6432c3820e9ba733ff (patch)
tree40bb04d66fcc4113e5af2f0e1cb8671385d10ac4
parent8b3ded404c25bf23221e3b5ff2cc873107185781 (diff)
core: Only use signalsafe functions inside signal handlers
The atexit() and signal() callbacks both need to only use signalsafe functions - that excludes the use of assert. So simplify fork_helper_exit_handler() and children_exit_handler(). __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95 0x00007fd630883d2b in _L_lock_13840 () from /lib/x86_64-linux-gnu/libc.so.6 0x00007fd630881df8 in __GI___libc_realloc (oldmem=0xfcb010, bytes=88) at malloc.c:3025 0x00007fd63087111b in _IO_vasprintf (result_ptr=0x7fff35dc4780, format=<optimised out>, args=args@entry=0x7fff35dc4658) at vasprintf.c:84 0x00007fd630852907 in ___asprintf (string_ptr=string_ptr@entry=0x7fff35dc4780, format=format@entry=0x7fd63097f718 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n") at asprintf.c:35 0x00007fd63082dd92 in __assert_fail_base (fmt=0x7fd63097f718 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x40cff5 "ret == 0", file=file@entry=0x4108d1 "igt_core.c", line=line@entry=872, function=function@entry=0x410ea0 <__PRETTY_FUNCTION__.8052> "children_exit_handler") at assert.c:57 0x00007fd63082dee2 in __GI___assert_fail (assertion=assertion@entry=0x40cff5 "ret == 0", file=file@entry=0x4108d1 "igt_core.c", line=line@entry=872, function=function@entry=0x410ea0 <__PRETTY_FUNCTION__.8052> "children_exit_handler") at assert.c:101 0x000000000040b03f in children_exit_handler (sig=<optimised out>) at igt_core.c:872 0x000000000040b089 in call_exit_handlers (sig=2) at igt_core.c:1029 fatal_sig_handler (sig=2) at igt_core.c:1053 <signal handler called> 0x00007fd6308bfe63 in __libc_fork () at ../nptl/sysdeps/unix/sysv/linux/x86_64/../fork.c:130 0x00007fd630bd6045 in __fork () at ../nptl/sysdeps/unix/sysv/linux/pt-fork.c:25 0x000000000040c51a in __igt_fork () at igt_core.c:900 0x00000000004036c2 in forking_evictions (ops=0x614360 <fault_ops>, surface_size=1048576, flags=5, trash_surfaces=<optimised out>, working_surfaces=338, fd=4) at eviction_common.c:203 test_forking_evictions (size=1048576, flags=5, count=338, fd=4) at gem_userptr_blits.c:1086 main (argc=1, argv=0x7fff35dc5328) at gem_userptr_blits.c:1478 Reported-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--lib/igt_core.c33
1 files changed, 9 insertions, 24 deletions
diff --git a/lib/igt_core.c b/lib/igt_core.c
index 29c969ba..0a2ddad9 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -793,19 +793,14 @@ static void reset_helper_process_list(void)
static void fork_helper_exit_handler(int sig)
{
+ int status;
+
+ /* Inside a signal handler, play safe */
for (int i = 0; i < ARRAY_SIZE(helper_process_pids); i++) {
pid_t pid = helper_process_pids[i];
- int status, ret;
-
if (pid != -1) {
- /* Someone forgot to fill up the array? */
- assert(pid != 0);
-
- ret = kill(pid, SIGTERM);
- assert(ret == 0);
- while (waitpid(pid, &status, 0) == -1 &&
- errno == EINTR)
- ;
+ kill(pid, SIGTERM);
+ waitpid(pid, &status, WNOHANG);
helper_process_count--;
}
}
@@ -902,21 +897,11 @@ void igt_wait_helper(struct igt_helper_process *proc)
static void children_exit_handler(int sig)
{
- int ret;
-
- assert(!test_child);
-
- for (int nc = 0; nc < num_test_children; nc++) {
- int status = -1;
- ret = kill(test_children[nc], SIGTERM);
- assert(ret == 0);
-
- while (waitpid(test_children[nc], &status, 0) == -1 &&
- errno == EINTR)
- ;
- }
+ int status;
- num_test_children = 0;
+ /* The exit handler can be called from a fatal signal, so play safe */
+ while (num_test_children-- && wait(&status))
+ ;
}
bool __igt_fork(void)