Based on @ccarton's response I've come up with a rough idea of what's happening. To illustrate:
~ truss -eaf /usr/bin/perl -e 'print "Test\n"; sleep 5' 2> >(dd bs=1 | wc -l)
In another terminal I could see this parent/child hierarchy:
bash
truss -eaf /usr/bin/perl -e printf "Test\n"; sleep 5
/usr/bin/perl -e printf "Test\n"; sleep 5
bash
dd bs=1
wc -l
truss
is waiting on the shell, but dd
won't exit until its stdin is closed ... so they deadlock.
~ truss -eaf -o >(some command) another command
... causes some command
to execute under the current shell so truss
is never its ancestor.
I saw the same hierarchy in Linux, but it doesn't deadlock.