Switch from at_exit to finalizer to avoid squashing test exit code.

Using at_exit can unintentionally squash the exit status of the including application's test suite, causing the suite to always return an exit status of 0 even when tests are failing. This causes CI platforms like Travis that rely on test exit status for determining the status of a given build. This commit uses a finalizer to trigger the same buffer flush without interfering with test suite exit status.