在OpenSSL中,错误堆栈和错误队列是否相同?
在openSSL文档中,我一直在阅读错误队列和错误堆栈。 这两种描述是否都指向相同的机制?或者它们是不同的机制 我一直在读取错误队列和错误堆栈。这两种描述是否都指向相同的机制?或者它们是不同的机制 据我所知,他们都是一样的,是付出还是索取。它们大多可以互换使用 错误队列是逻辑性的,它通常被抽象地讨论。库至少有两个不同的错误队列。第一个是来自在OpenSSL中,错误堆栈和错误队列是否相同?,openssl,Openssl,在openSSL文档中,我一直在阅读错误队列和错误堆栈。 这两种描述是否都指向相同的机制?或者它们是不同的机制 我一直在读取错误队列和错误堆栈。这两种描述是否都指向相同的机制?或者它们是不同的机制 据我所知,他们都是一样的,是付出还是索取。它们大多可以互换使用 错误队列是逻辑性的,它通常被抽象地讨论。库至少有两个不同的错误队列。第一个是来自libcrypto的,您可以使用ERR\u get\u error获取其错误。第二个是来自libssl,您可以使用SSL\u get\u error获取错误
libcrypto
的,您可以使用ERR\u get\u error
获取其错误。第二个是来自libssl
,您可以使用SSL\u get\u error
获取错误
错误堆栈实际上是错误队列的一个实现。下面是libcrypto在代码中的样子。它在crypto/err/err.h
中声明,并在crypto/err/err.c
中实现:
unsigned long ERR_get_error(void)
{
return (get_error_values(1, 0, NULL, NULL, NULL, NULL));
}
以及:
以及:
ERR.*
是一个队列,主要用于实际错误SSL\u get\u error()
是独立的,但不是队列;它是单个小整数值,用于真实错误和有效但需要区分的情况;一个更准确但不太方便的名称是SSL\u获取\u任何\u状态\u除了\u完全\u正常\u完成\u操作()
。请检查我的理解。如果以SSL_read()为例:在调用SSL_read()之前,我调用ERR_clear_error(),然后调用SSL_read(),如果从SSL_read()返回
static unsigned long get_error_values(int inc, int top, const char **file,
int *line, const char **data,
int *flags)
{
int i = 0;
ERR_STATE *es;
unsigned long ret;
es = ERR_get_state();
if (inc && top) {
if (file)
*file = "";
if (line)
*line = 0;
if (data)
*data = "";
if (flags)
*flags = 0;
return ERR_R_INTERNAL_ERROR;
}
if (es->bottom == es->top)
return 0;
if (top)
i = es->top; /* last error */
else
i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */
ret = es->err_buffer[i];
if (inc) {
es->bottom = i;
es->err_buffer[i] = 0;
}
if ((file != NULL) && (line != NULL)) {
if (es->err_file[i] == NULL) {
*file = "NA";
if (line != NULL)
*line = 0;
} else {
*file = es->err_file[i];
if (line != NULL)
*line = es->err_line[i];
}
}
if (data == NULL) {
if (inc) {
err_clear_data(es, i);
}
} else {
if (es->err_data[i] == NULL) {
*data = "";
if (flags != NULL)
*flags = 0;
} else {
*data = es->err_data[i];
if (flags != NULL)
*flags = es->err_data_flags[i];
}
}
return ret;
}
ERR_STATE *ERR_get_state(void)
{
static ERR_STATE fallback;
ERR_STATE *ret, tmp, *tmpp = NULL;
int i;
CRYPTO_THREADID tid;
err_fns_check();
CRYPTO_THREADID_current(&tid);
CRYPTO_THREADID_cpy(&tmp.tid, &tid);
ret = ERRFN(thread_get_item) (&tmp);
/* ret == the error state, if NULL, make a new one */
if (ret == NULL) {
ret = (ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
if (ret == NULL)
return (&fallback);
CRYPTO_THREADID_cpy(&ret->tid, &tid);
ret->top = 0;
ret->bottom = 0;
for (i = 0; i < ERR_NUM_ERRORS; i++) {
ret->err_data[i] = NULL;
ret->err_data_flags[i] = 0;
}
tmpp = ERRFN(thread_set_item) (ret);
/* To check if insertion failed, do a get. */
if (ERRFN(thread_get_item) (ret) != ret) {
ERR_STATE_free(ret); /* could not insert it */
return (&fallback);
}
/*
* If a race occured in this function and we came second, tmpp is the
* first one that we just replaced.
*/
if (tmpp)
ERR_STATE_free(tmpp);
}
return ret;
}
$ grep -IR ERR_STATE * | grep DECLARE
crypto/err/err.c:DECLARE_LHASH_OF(ERR_STATE);