在openSSL文档中,我一直在阅读错误队列和错误堆栈。 两个描述都指的是相同的机制吗?或者它们是不同的机制?
答案 0 :(得分:2)
我一直在阅读错误队列和错误堆栈。两个描述都指的是相同的机制吗?或者它们是不同的机制?
据我所知,他们是一样的,给予或接受。它们大多可以互换使用。
错误队列是合乎逻辑的,通常会对其进行抽象讨论。该库至少有两个不同的错误队列。第一个是libcrypto
中的一个,您使用ERR_get_error
获取错误。第二个是libssl
中的一个,您使用SSL_get_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));
}
和
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);