void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u),
                         void *u)
{
    CRYPTO_THREAD_ID tid = CRYPTO_THREAD_get_current_id();
    unsigned long l;
    char buf[256];
    char buf2[4096], *hex;
    const char *file, *data;
    int line, flags;

    while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
        ERR_error_string_n(l, buf, sizeof(buf));
        hex = OPENSSL_buf2hexstr((const unsigned char *)&tid, sizeof(tid));
        BIO_snprintf(buf2, sizeof(buf2), "%s:%s:%s:%d:%s\n", hex, buf, file,
                     line, (flags & ERR_TXT_STRING) ? data : "");
        OPENSSL_free(hex);
        if (cb(buf2, strlen(buf2), u) <= 0)
            break;              /* abort outputting the error report */
    }
}