很多GNU C库里的函数都会侦测并报告错误条件。我们的程序需要检测这些错误条件。比如:我们打开一个输入文件时需要判断该文件是否正确的打开。如果没有正确打开,我们需要打印错误或者采取其他正确的方式。为了利用这种错误报告机制,我们需要包含头文件errno.h

检测错误:

  很多库函数都会返回一个特殊的值来显示函数运行出错。常见的特殊值有:-1、空指针、EOF常量。但是这些返回值只能告诉你有错误产生,但不会告诉你错误是什么。如果你想知道错误是什么,就得靠错误代码,错误代码存储在变量errno中(在errno.h中有声明)

  errno变量包含了系统错误代码,其类型是volatile。该类型意味着其可以突然被异步线程改变,编译器从不假设其值。如果你在写信号处理程序应当保存改变量的值并恢复其值。

  errno的初始值为0,遇到错误时,errno绝无可能为0。但没有错误的时候,errno也不一定为0(库函数在成功运行时并不会修改errno的值)。所以,不要依据errno的值来判断错误是否发生。正确的做法是为每一个函数做好文档,标注出错误代码的值对应的错误类型。这样调用失败时,你可以通过检查errno获取错误代码,然后查询函数文档获取错误详情。如果你想获取某一库函数的错误代码,最好再次之前设置errno为0(或许你还想先保存以下errno的值,然后便于恢复该值)。

  每一个错误代码都有一个以E开头紧跟大写字母或数字的符号名,实际为定义在errno.h中的宏。当然不是所有的宏都定义在一个errno.h中(详细的可以自己翻一翻头文件,注意不仅仅只有一个errno.h,多个errno.h共同定义了全部的宏)

  错误代码的值一般为正数并且都不相同,但也有一个例外:EWORLDBLOCK和EAGAIN的错误代码是一样的。除了EWORLDBLOCK和EAGAIN,你可以使用switch语句来判断错误代码。但你不应该依赖于此,你唯一可以相信的就是文档。

  除了GNU/Hurd系统,几乎所有的系统调用被传入一个无效指针时都会返回EFAULT。所以呢,glibc的函数库说明文档中往往会省略对EFAULT的解释。

  大多数的错误代码宏名都显而易见的好懂,如果实在不知其意可以查看手册或者

~# man errno

这里简单提几个宏:

Macro: int EDOM
域错误,可以理解为定义域错误。主要用在数学函数中。如果数学函数的一个参数值不在函数定义域中,则会将errno设置为EDOM Macro: int ERANGE
范围错误,与上面的EDOM恰好相反。EDOM是定义域的话,ERANGER就是值域了。也多用于数学函数中。如果数学函数返回值超过了约定的返回,则会将errno设置为ERANGE Macro: int EAGAIN
资源暂时不可获得。这种错误可能是随机的,你再次运行的时候便好了。。。EWOULDBLOCK是EAGAIN的一个别名。

错误消息:

  我们知道错误代码,但总觉得查文档不方便。幸好库文件给我们提供了错误消息报告函数。这些函数可以报告一个具有说明性的错误消息。部分消息报告函数我们可以自己定义消息格式。

  函数strerror和perror为每一个错误代码都提供了一个标准的错误消息。而变量program_invocation_short_name则可以方便获取程序的名字,告诉我们哪个程序出错。

几个函数原型:

#include <string.h>
char * strerror(int errnum);
char *strerror_r(int errnum, char *buf, size_t n);

说明:  strerror和strerror_r两个函数差不多。区别在于安全性,官方文档对strerror的注释是MT-Unsafe race:strerror,而strerror_r则为MT-Safe。strerror返回一个静态申请的字符串缓冲区,该缓冲区被所有线程共享。而strerror_r返回的是一个私有副本,并不被其他线程共享。另外这两个函数都有可能造成内存溢出(静态申请的缓冲区)。尽管strerror_r可以指定字符串长度,但这长度是char *buf的。这函数有两个返回值,一个使用reurn返回,还有一个是char *buf。return返回的依旧是一个静态缓冲区。

#include<stdio.h>
void perror(const char *message);

说明:  perror将error message打印到标准错误输出中。如果你传进的参数是一个空指针,perror会根据errno打印错误消息。如果char *message非空,perror会将message当作错误消息的前缀输出。perror得立即调用,不然errno的值可能发生变化。

char *program_invocation_name; //等同于argv[0]
char *program_invocation_short_name //不包含目录名。

说明:  这两个变量的初始化工作由glibc库在还未调用main函数之前执行。所以在非GNU库中,这两个变量不起效果,在实际代码中我们需要定义_GNU_SOURCE宏,告诉编译器使用GNU库。

  以下两个函数在整个GNU project中使用非常广泛。

void error(int status, int errnum, const char *format, ...);
void error_at_line(int status, int errnum, const char *fname, unsigned int lineno, const char *format, ...);

说明:  这两个函数的返回和status有关,如果status是0,则正常格式化打印错误消息。全局变量error_message_count也会做自增操作。错误消息的格式如下:program_name: format_string: error_messager_for_errno\n。如果status非零,这两个函数将调用exit status,即以状态status退出(不会返回)。关于program_name:全局变量error_print_progname指向的函数决定了program_name的值。error_at_line函数有点特别:多了fname,lineno两个参数。错误消息格式如下:program_name:fname:lineno format_string: error_mesage_for_errno\n。如果全局变量error_one_per_line被设置为非零值,每一行只会打印一个错误消息。

  除了以上的错误消息函数,我们还有以下几个:这几个函数主要用在BSD系统中,定义在头文件err.h中,在gnu系统中不推荐使用。

void warn(const char *format, ...)
void vwarn(const char *format, va_list ap)
void warnx(const char *format, ...)
void vwarnx(const char *format, va_list ap)
void err(int status, const char *format, ...)
void verr(int status, const char *format, va_list ap)
void errx(int status, const char *format, ...)
void verrx(int status, const char *format, va_list ap)

各位看官自行查看手册吧。just be a man!!!

转自:http://www.cnblogs.com/san-fu-su/p/5731000.html

glibc_error reporting的更多相关文章

  1. SQL Server性能计数器收集汇总方案(Reporting Service)

    通过收集计数器信息,并将计数器信息汇总为不同粒度存储,以Reporting Service报表服务器显示.以下是计数器收集汇总的基本架构. 笔者需要收集的SQL Server计数器包括:SQL Ser ...

  2. 迁移Reporting Services的方法与WMI错误

    今天上午,接到一个任务:迁移SQL SERVER 2005的报表服务到另外一台SQL SERVER 2008服务器,结果等我备份了两边服务器的ReportServer,ReportServerTemp ...

  3. SQL SERVER 2008 Reporting Services 的一些小问题集合

    实验环境:服务器  Windows Server  2008 R2 Standard 64bit                   数据库  SQL SERVER 2008 R2 Standard ...

  4. Reporting Service 服务启动时报错The service did not respond to the start or control request in a timely fashion

    案例环境: 启动一台数据库服务器(Windows Server 2003)的Reporting Service(SQL Server 2008 R2)服务时,出现如下错误信息: System.Inva ...

  5. SQL Server 2008 标准版不支持Reporting Services的数据驱动订阅

    今天开发同事找我,说为什么Reporting Services服务器的报表管理的订阅选项里面只有"新建订阅"选项, 没有"数据驱动订阅"选项,说实话,我也基本上 ...

  6. 数据库服务器改名导致Reporting Service不可用的案例

    案例环境: 操作系统版本    :    Windows Server 2012 R2 Standard 数据库版本      :   SQL Server 2012 Standard Edition ...

  7. Reporting Services 错误案例一则

    遇到一个有意思的Reporting Services报表的案例,在2015-01-30号的凌晨20分左右的时候,有人发现Reporting Services的速度非常慢,而且最后有抛出异常,当时不知道 ...

  8. Reporting Service 告警"w WARN: Thread pool pressure. Using current thread for a work item"

    如果Reporting Service偶尔出现不可访问或访问出错情况,这种情况一般没有做监控的话,很难捕捉到.出现这种问题,最好检查Reporting Service的日志文件. 今天早上就遇到这样一 ...

  9. (转载)SQL Reporting Services (Expression Examples)

    https://msdn.microsoft.com/en-us/library/ms157328(v=SQL.100).aspx Expressions are used frequently in ...

随机推荐

  1. GlobalMemoryStatus 和 GlobalMemoryStatusEx

    1.获取系统内存信息有2个api,分别是GlobalMemoryStatus和GlobalMemoryStatusEx.GlobalMemoryStatus函数可以在C语言里直接调用,但是Global ...

  2. 安全配置基线Linux系统

    Linux系统安全配置基线 一:共享账号检查 配置名称:用户账号分配检查,避免共享账号存在 配置要求:1.系统需按照实际用户分配账号: 2.避免不同用户间共享账号,避免用户账号和服务器间通信使用的账号 ...

  3. duplicate symbols for architecture

    duplicate symbols for architecture   XCODE编译的时候报错:duplicate symbols for architecture armv7   1.首先排查是 ...

  4. Erlang/OTP 中文手册

    http://erldoc.com/ Open Telecom Platform application array asn1rt base64 binary calendar code dbg di ...

  5. HDU 1081 To The Max - 最大字段和

    传送门 题目大意: 求一个矩阵的最大子矩阵和. 题目分析: 刚开始考虑了一下dp方程的递推,但是不好转.简便的方法是预处理sum[i][j]表示第i行的前j个元素之和,之后\(n^3\)枚举子矩阵就可 ...

  6. 使用RpcLite构建SOA/Web服务

    使用RpcLite构建SOA/Web服务 SOA框架系列 1. 使用RpcLite构建SOA/Web服务 提到Web服务最先想到的就是WebService此外常用的还有WCF.ServiceStack ...

  7. 对Java JVM中类加载几点解释

    1.用到类的时候,类加载到方法区,同时方法区会存放static的内容(包括静态方法和静态变量),随类的加载而加载 2当new的时候,会在堆中创建一个对象,在其中会开辟其中的实例变量内存并初始化,堆中变 ...

  8. tensorflow 函数接口的理解

    1. tf.nn.softmax tf.nn.softmax(logits, dim=-1, name=None) w*x+b ⇒ logits softmax 函数执行的操作:exp(logits) ...

  9. 【Cocos2d-x Lua】数据库封装类型的操作

    Lua数据库封装类型的操作 使用演示样例 lua代码: require("DB") -- 保存一个字符串(数据库中存储的数据都是以字符串的形式保存的) DB:getInstance ...

  10. 经Gradle采取Jenkins的build

    如今,企业都太多Jenkins去管理apk,后该代码被提交jenkins在生成build 因此,我们可以得到jenkins提交版本 Jenkins在编制job什么时候,有一个内置的可变BUILD_NU ...