如何生成有意义的OpenSSL 1.0.2错误信息?实现相关疑问
OpenSSL 1.0.2 错误信息收集问题解答
你的处理流程合理性分析
你当前的错误处理逻辑整体方向是正确的:初始化加载错误字符串、调用SSL函数前清空错误队列、失败后通过SSL_get_error()获取一级分类码、针对特定错误读取详细错误队列的思路,完全符合OpenSSL的错误处理规范。你后续更新的循环调用ERR_get_error()直到返回0的代码,也修正了之前仅读取单个错误的问题,这是正确的做法。
针对你的疑问逐一解答
1. 该方法是否能获取所有相关错误?
只要遵循正确调用顺序,这个方法可以覆盖绝大多数SSL相关错误:
- 对于
SSL_ERROR_SSL:错误队列会包含SSL库内部的完整错误链,循环读取能获取所有层级的错误信息 - 对于
SSL_ERROR_SYSCALL:除了OpenSSL自身的错误(若存在),结合strerror(errno)能获取系统调用层面的错误(如socket读写失败、文件操作错误等) - 特殊情况:部分场景下
SSL_ERROR_SYSCALL可能无对应OpenSSL错误(比如连接被重置时ERR_get_error()返回0),此时仅记录strerror(errno)即可
2. 是否需要多次调用ERR_get_error()?何时停止?
是的,必须循环调用直到返回0。OpenSSL错误队列是栈结构,每次调用ERR_get_error()会取出队列顶部的错误码,队列为空时返回0。如果仅调用一次,会丢失后续的链式错误信息,你更新后的while循环逻辑完全正确。
3. 能否将SSL_get_error()的返回值传入ERR_error_string()使用?
绝对不可以。SSL_get_error()返回的是SSL层的错误分类码(如SSL_ERROR_SYSCALL、SSL_ERROR_WANT_READ等),这类码属于SSL模块专属的分类标识,不属于OpenSSL通用错误码空间。ERR_error_string()仅能解析ERR_get_error()返回的复合错误码(包含库标识、函数标识、原因码的32位编码),即使提前调用SSL_load_error_strings()也无法将SSL分类码转换为有效字符串。
额外优化建议
- 缓冲区安全:每次调用
snprintf前务必确认剩余缓冲区空间,避免错误信息过长导致溢出 - 非致命错误处理:
SSL_ERROR_WANT_READ/SSL_ERROR_WANT_WRITE属于重试类错误,无需读取错误队列,仅需重试当前操作即可 - 线程安全:
ERR_error_string()返回静态缓冲区,多线程环境下会被覆盖,建议使用ERR_error_string_n();strerror同理,推荐使用线程安全的strerror_r
优化后的参考代码
int error0 = SSL_get_error(ssl, err); snprintf(msg + strlen(msg), sizeof(msg) - strlen(msg), "SSL_get_error:%d;", error0); // 仅针对致命错误读取错误队列 if (error0 == SSL_ERROR_SYSCALL || error0 == SSL_ERROR_SSL) { unsigned long error1; // 注意:ERR_get_error()返回值为unsigned long,避免截断 while ((error1 = ERR_get_error()) != 0) { char err_buf[256]; // 线程安全的错误字符串获取方法 ERR_error_string_n(error1, err_buf, sizeof(err_buf)); snprintf(msg + strlen(msg), sizeof(msg) - strlen(msg), " ERR_get_error:%lu;%s;", error1, err_buf); } if (error0 == SSL_ERROR_SYSCALL) { char sys_err_buf[256]; // 跨平台线程安全的系统错误字符串获取 #ifdef _GNU_SOURCE strerror_r(errno, sys_err_buf, sizeof(sys_err_buf)); #else strerror_r(errno, sys_err_buf, sizeof(sys_err_buf)); // POSIX标准版本 #endif snprintf(msg + strlen(msg), sizeof(msg) - strlen(msg), " strerror:%s", sys_err_buf); } }
内容的提问来源于stack exchange,提问作者Athazo
相关产品推荐
相关产品推荐

