public static Socket fork(ZContext ctx, IAttachedRunnable runnable, Object... args)
    {
        Socket pipe = ctx.createSocket(SocketType.PAIR);
        assert (pipe != null);
        pipe.bind(String.format(Locale.ENGLISH, "inproc://zctx-pipe-%d", pipe.hashCode()));

        //  Connect child pipe to our pipe
        ZContext ccontext = ctx.shadow();
        Socket cpipe = ccontext.createSocket(SocketType.PAIR);
        assert (cpipe != null);
        cpipe.connect(String.format(Locale.ENGLISH, "inproc://zctx-pipe-%d", pipe.hashCode()));

        //  Prepare child thread
        Thread shim = new ShimThread(ccontext, runnable, args, cpipe);
        shim.start();

        return pipe;
    }
@Test(timeout = 1000)
    public void testCriticalException() throws InterruptedException
    {
        final CountDownLatch stopped = new CountDownLatch(1);
        try (final ZContext ctx = new ZContext()) {
            ctx.setUncaughtExceptionHandler((t, e) -> stopped.countDown());
            Socket pipe = ZThread.fork(ctx, (args, ctx1, pipe1) -> {
                throw new Error("critical");
            });
            assertThat(pipe, notNullValue());
            stopped.await();
        }
    }