当经典的 Linux C/C++ 软件出现问题时,我们有神奇的变量 errno,它可以为我们提供有关刚刚出现问题的线索。
但是这些错误是在哪里定义的呢?
让我们举个例子(它实际上是 Qt 应用程序的一部分,因此是 qDebug())。
if (ioctl(file, I2C_SLAVE, address) < 0) {
int err = errno;
qDebug() << __FILE__ << __FUNCTION__ << __LINE__
<< "Can't set address:" << address
<< "Errno:" << err << strerror(err);
....
下一步是查看 errno 是什么,以便我们决定是退出还是尝试解决该问题。
所以我们可能会在此时添加一个 if 或 switch。
if (err == 9)
{
// do something...
}
else
{
//do someting else
}
我的问题是在哪里可以找到“9”代表的错误? 我不喜欢代码中的那种神奇数字。
/谢谢
它们通常在
/usr/include/errno.h
* 中定义,并且可以通过包含 errno.h 来访问:
#include <errno.h>
报错时我会写出errno值及其文字含义,通过
strerror()
获取文字含义:
if (something_went_wrong)
{
log("Something went wrong: %s (%d)", strerror(errno), errno);
return false;
}
但是,在 Linux shell 中,您可以使用
perror
实用程序来了解不同 errno 值的含义:
$ perror 9
OS error code 9: Bad file descriptor
编辑: 您的代码应该更改为使用符号值:
if (err == EBADF)
{
// do something...
}
else
{
//do someting else
}
编辑2:*在Linux下,至少在
/usr/include/asm-generic/{errno,errno-base}.h
和其他地方定义了实际值,如果你想查看它们,找到它们会有点痛苦。
NAME
errno - number of last error
SYNOPSIS
#include <errno.h>
DESCRIPTION
The <errno.h> header file defines the integer variable errno, which is set by system calls and some library functions in the event of an error to indicate
what went wrong. Its value is significant only when the return value of the call indicated an error (i.e., -1 from most system calls; -1 or NULL from most
library functions); a function that succeeds is allowed to change errno.
Valid error numbers are all non-zero; errno is never set to zero by any system call or library function.
通常要实现错误处理,您需要知道函数可以返回哪些特定错误代码。此信息可在 man 或 http://www.kernel.org/doc/man-pages/.
中找到。例如,对于 ioctl 调用,您应该期待以下代码:
EBADF d is not a valid descriptor.
EFAULT argp references an inaccessible memory area.
EINVAL Request or argp is not valid.
ENOTTY d is not associated with a character special device.
ENOTTY The specified request does not apply to the kind of object that the
descriptor d references.
编辑: 如果包含
<errno.h>
,则定义所有可能的错误代码的所有文件也都包含在内,因此您实际上不需要知道它们的确切位置。
该文件是:
/usr/include/errno.h
--p
与 errno 相关的错误消息无法正确解释 I2C 错误。
I2C 错误必须根据此列表进行解释:
https://docs.kernel.org/i2c/fault-codes.html
例如,
OSError: [Errno 6] No such device or address
并不表示缺少任何设备或地址!
相反,当 I2C 通信未收到 ACK 时(例如,当 2 个 I2C 消息同时发送到同一 I2C 设备时),就会发生这种情况。
为了将 errno 与故障代码的名称相匹配(例如从 errno 6 到
ENXIO
),您可以检查:
cat /usr/include/asm-generic/errno*.h