20140603 对error.c 用于分析源代码

20140603
对error.c 用于分析源代码


继续看error.c该功能
买家现在将自己的代码和数据汇编例如,下面的:
  1.#include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 #include <stdarg.h>
  5 #include <pthread.h>
  6 #include "error.h"
  7 #include "dxyh_thread.h"
  8 #include "record.h"
  9 #include "dxyh.h"
 10 
 11 static void err_handle(int errnoflg, int thread_err_code,
 12                 const char *fmt, va_list ap);
 13 
 14 /*
 15  * err_sys -- print system error msg
 16  */
 17 void err_sys(const char *cause, ...)
 18 {
 19         va_list ap;
 20 
 21         va_start(ap, cause);
 22         err_handle(1, 0, cause, ap);
 23         va_end(ap);
 24         return;
 25 } /* end err_sys */
 26 
 27 /*
 28  * err_msg -- print normal err msg
 29  */
 30 void err_msg(const char *cause, ...)
 31 {
 32         va_list ap;
 33 
 34         va_start(ap, cause);
 35         err_handle(0, 0, cause, ap);
 36         va_end(ap);
 37         return;
 38 }  /* end err_msg */
 39 
 40 /*
 41  * t_err_sys -- thread print system error msg, the quit
 42  */
 43 void t_err_sys(int thread_err_code, const char *cause, ...)
 44 {
 45         va_list ap;
 46 
 47         va_start(ap, cause);
 48         err_handle(2, thread_err_code, cause, ap);
 49         va_end(ap);
 50         exit(EXIT_FAILURE);
 51 } /* end t_err_sys */
 52 
 53 /*
 54  * err_handle -- error handle function
 55  * @errnoflg: if none zero will show sys err, otherwise not
 56  * @thread_err_code: error code in thread
 57  * @fmt: err string format wants printing
 58  * @ap: handle argument
 59  */
 60 static void err_handle(int errnoflg, int thread_err_code,
 61                         const char *fmt, va_list ap)
 62 {
 63         int errno_save, n;
 64         char buf[MAXLINE];
 65 
66         vsnprintf(buf, sizeof(buf), fmt, ap);
 67         n = strlen(buf);
 68                 /*If want to show system error msg*/
 69         if (1 == errnoflg) {
 70                 /*Save errno, because 'strerror' may modify it*/
 71                 errno_save = errno;
 72                 snprintf(buf+n, sizeof(buf)-n,
 73                                 ": %s", strerror(errno_save));
 74         }
 75         else if (2 == errnoflg)
 76                 snprintf(buf+n,
 77                                 sizeof(buf)-n,": %s",strerror(thread_err_cod    e));
 78         strcat(buf, "\n");
 79 
 80                 /*Output the final error msg*/
 81         fflush(stdout); /*In case stdout and stderr are the same*/
 82         my_lock_mutex_wait();
 83         fputs(buf, stderr);
 84         my_lock_mutex_release();
 85         fflush(stderr);
 86         return ;
 87 } /* end err_handle */
~                              








errno
errno - number of last error
errno 记录系统的最后一次错误代码。

代码是一个int型的值。在errno.h中定义
if (somecall() == -1) {
printf("somecall() failed\n");
if (errno == ...) { ... }
}
这种样例并不能得到somecall这个函数的执行所产生的错误代码。由于非常可能是printf这个函数产生的。


if (somecall() == -1) {
int errsv = errno;
printf("somecall() failed\n");
if (errsv == ...) { ... }
这样才干真正得到执行somecall函数多带来的错误代码。
}
注意:仅仅有当一个库函数失败时,errno才会被设置。当函数成功执行时,errno的值不会被改动。这意味着我们不能通过測试errno的值来推断是否有错误存在。反之。仅仅有当被调用的函数提示有发生错误时检查errno的值才有意义。
查看错误代码errno是调试程序的一个重要方法。

当linux C api函数发生异常时,通常会将errno变量(需include errno.h)赋一个整数值,不同的值表示不同的含义,能够通过查看该值猜測出错的原因。在实际编程中用这一招攻克了不少原本看来莫名其妙的问题。


2errno的一些错误定义
编辑


下面来主要自2.6.32的内核代码中的/usr/include/asm-generic/errno.h及errno-base.h。输出错误原因定义归纳整理例如以下:
#define EPERM 1 /* Operation not permitted */
  #define ENOENT 2 /* No such file or directory */
  #define ESRCH 3 /* No such process */
  #define EINTR 4 /* Interrupted system call */
  #define EIO 5 /* I/O error */
  
                 :
                  :
                  :
  
  #define ERFKILL 132 /* Operation not possible due to RF-kill */
  #define EHWPOISON 133 /* Memory page has hardware error */
  
  fflush
  fflush(stdin)刷新标准输入缓冲区,把输入缓冲区里的东西丢弃[非标准]
  fflush(stdout)刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上
  
  
  
  _vsnprintf
  编辑
  _vsnprintf,C语言库函数之中的一个,属于可变參数。用于向字符串中打印数据、数据格式用户自己定义。
  头文件:
  #include <stdarg.h>
  函数声明:
  int_vsnprintf(char*str,size_tsize,constchar*format,va_listap);
  參数说明:
  char *str [out],把生成的格式化的字符串存放在这里.
  size_t size [in], str可接受的最大字节数,防止产生数组越界.
  const char *format [in], 指定输出格式的字符串。它决定了你须要提供的可变參数的类型、个数和顺序。


  va_list ap [in], va_list变量. va:variable-argument:可变參数
  函数功能:将可变參数格式化输出到一个字符数组。


  使用方法类似于vsprintf,只是加了size的限制。防止了内存溢出(size为str所指的存储空间的大小)。
  返回值:运行成功,返回写入到字符数组str中的字符个数(不包括终止符)。最大不超过size。运行失败,返回负值。并置errno.[1]
  
  
  int snprintf(char *str, size_t size, const char *format, ...);


  将可变个參数(...)依照format格式化成字符串,然后将其拷贝到str中
  (1) 假设格式化后的字符串长度 < size,则将此字符串所有拷贝到str中。并给其后加入一个字符串结束符('\0');
  (2) 假设格式化后的字符串长度 >= size。则仅仅将当中的(size-1)个字符拷贝到str中。并给其后加入一个字符串结束符('\0')。返回值为格式化后的字符串的长度。


  char a[20];
  i = snprintf(a, 9, "%012d", 12345);
  printf("i = %d, a = %s", i, a);
  输出为:i = 12, a = 00000001
  3所需头文件
  编辑
  
  #include <stdio.h>
  4函数返回值
  编辑
  
  若成功则返回欲写入的字符串长度,若出错则返回负值。


  5说明
  编辑
  
  strcpy() sprintf() strcat() 存在安全隐患。 其相应的安全版为:
  strncpy() snprintf() strncat()
  1
  snprintf(s, 100, "%.*S", 3, "abcd");
  s的值为abc
  %.*s 表示有两项, 第一项指定了长度,第二项则是%s的内容。所以取前三位
  #if _MSC_VER
  #define snprintf _snprintf
  #endif
  通用ANSI UNICODE 通用定义
  1
  _sntprintf
  6样例
  #include <stdio.h>
  #include <stdlib.h>
  int main()
  {      
      char str[10]={0}; 
      snprintf(str, sizeof(str), "0123456789012345678"); 
      printf("str=%s \n", str); return 0;
  }
  执行结果:str=012345678
  头文件
  <stdio.h>[1]

版权声明:本文博主原创文章,博客,未经同意不得转载。

posted @ 2015-09-12 13:16  hrhguanli  阅读(209)  评论(0编辑  收藏  举报