glibc_error reporting
很多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的更多相关文章
- SQL Server性能计数器收集汇总方案(Reporting Service)
通过收集计数器信息,并将计数器信息汇总为不同粒度存储,以Reporting Service报表服务器显示.以下是计数器收集汇总的基本架构. 笔者需要收集的SQL Server计数器包括:SQL Ser ...
- 迁移Reporting Services的方法与WMI错误
今天上午,接到一个任务:迁移SQL SERVER 2005的报表服务到另外一台SQL SERVER 2008服务器,结果等我备份了两边服务器的ReportServer,ReportServerTemp ...
- SQL SERVER 2008 Reporting Services 的一些小问题集合
实验环境:服务器 Windows Server 2008 R2 Standard 64bit 数据库 SQL SERVER 2008 R2 Standard ...
- 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 ...
- SQL Server 2008 标准版不支持Reporting Services的数据驱动订阅
今天开发同事找我,说为什么Reporting Services服务器的报表管理的订阅选项里面只有"新建订阅"选项, 没有"数据驱动订阅"选项,说实话,我也基本上 ...
- 数据库服务器改名导致Reporting Service不可用的案例
案例环境: 操作系统版本 : Windows Server 2012 R2 Standard 数据库版本 : SQL Server 2012 Standard Edition ...
- Reporting Services 错误案例一则
遇到一个有意思的Reporting Services报表的案例,在2015-01-30号的凌晨20分左右的时候,有人发现Reporting Services的速度非常慢,而且最后有抛出异常,当时不知道 ...
- Reporting Service 告警"w WARN: Thread pool pressure. Using current thread for a work item"
如果Reporting Service偶尔出现不可访问或访问出错情况,这种情况一般没有做监控的话,很难捕捉到.出现这种问题,最好检查Reporting Service的日志文件. 今天早上就遇到这样一 ...
- (转载)SQL Reporting Services (Expression Examples)
https://msdn.microsoft.com/en-us/library/ms157328(v=SQL.100).aspx Expressions are used frequently in ...
随机推荐
- $.getJSON 跨域
//支持跨域 $.getJSON(url + '&callback=?', function(res) { if (res.status === 0) { console.log(res.re ...
- CentOS下安装和配置MySQL-JDK-Tomcat-Nginx(个人官网环境搭建手册)
今天,重新弄我的个人云主机的环境,准备运营自己用Java写的个人官网等网站. 服务器环境:阿里云CentOS 6.4位 包括以下脚本在内的绝大部分命令和脚本,都是我亲自执行过,靠谱的. 完整的&quo ...
- RGCDQ(线段树+数论)
题意:求n和m之间的全部数的素因子个数的最大gcd值. 分析:这题好恶心.看着就是一颗线段树.但本题有一定的规律,我也是后来才发现,我还没推出这个规律.就不说了,就用纯线段树解答吧. 由于个点数都小于 ...
- nginx源代码分析--ngx_http_optimize_servers()函数
这个函数做了连部分工作:1)以port为入口点 将实用的信息存放到hash表内 2)调用ngx_http_init_listening()函数 对port进行监听 1. 在ngx_http_core_ ...
- Android Studio Gradle:Resolvedependencies':app:_debugCompile' 问题解决纪录
问题描述: 第一次使用AndroidStudio打开已经存在的AndroidStudio项目,卡在Gradle:Resolvedependencies':app_debugCompile'步骤,即使进 ...
- MQ选型对比RabbitMQ RocketMQ ActiveMQ
原文:MQ选型对比RabbitMQ RocketMQ ActiveMQ 几种MQ产品说明: ZeroMQ : 扩展性好,开发比较灵活,采用C语言实现,实际上他只是一个socket库的重新封装 ...
- c# 安全队列
using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Linq; ...
- 将asp.net core2.0项目部署在IIS上运行
原文:将asp.net core2.0项目部署在IIS上运行 前言: 与ASP.NET时代不同,ASP.NET Core不再是由IIS工作进程(w3wp.exe)托管,而是独立运行的.它独立运行在控 ...
- Path类的最全面具体解释 - 自己定义View应用系列
前言 自己定义View是Android开发人员必须了解的基础:而Path类的使用在自己定义View绘制中发挥着很关键的数据 网上有大量关于自己定义View中Path类的文章.但存在一些问题:内容不全. ...
- js进阶 10-4 jquery中基础选择器有哪些
js进阶 10-4 jquery中基础选择器有哪些 一.总结 一句话总结: 1.群组选择器用的符号是什么? 群组选择器,中间是逗号 2.jquery中基础选择器有哪些? 5种,类,id,tag,群组, ...