nginx源码学习——错误处理
2015-05-10 00:24
477 查看
2015-05-09 wcdj
nginx在的main入口函数中(src/core/nginx.c),首先会调用ngx_strerror_init函数完成对错误码和错误信息的初始化,为什么这么做呢?继续看下内部实现。
此函数定义在src/os/unix/ngx_errno.c中:
作者解释为什么要把strerror()对应的错误信息描述复制一份,即ngx_sys_errlist。原因如下:
1)strerror()和strerror_r()函数都不是Async-Signal-Safe,因此,它们不能用在信号的处理函数中;
2)但是使用ngx_sys_errlist数组代替strerror()和strerror_r()函数,Linux上的链接器会产生告警;
使用ngx_sys_errlist数组实际是调用src/os/unix/ngx_errno.c中的ngx_strerror函数:
即,ngx_strerror函数会根据错误码入参,将ngx_sys_errlist数组中的对应的错误信息拷贝给调用者提供的buffer中,供调用者使用。
nginx在的main入口函数中(src/core/nginx.c),首先会调用ngx_strerror_init函数完成对错误码和错误信息的初始化,为什么这么做呢?继续看下内部实现。
此函数定义在src/os/unix/ngx_errno.c中:
static ngx_str_t *ngx_sys_errlist; static ngx_str_t ngx_unknown_error = ngx_string("Unknown error"); ngx_uint_t ngx_strerror_init(void) { char *msg; u_char *p; size_t len; ngx_err_t err; /* * ngx_strerror() is not ready to work at this stage, therefore, * malloc() is used and possible errors are logged using strerror(). */ len = NGX_SYS_NERR * sizeof(ngx_str_t); ngx_sys_errlist = malloc(len); if (ngx_sys_errlist == NULL) { goto failed; } for (err = 0; err < NGX_SYS_NERR; err++) { msg = strerror(err); len = ngx_strlen(msg); p = malloc(len); if (p == NULL) { goto failed; } ngx_memcpy(p, msg, len); ngx_sys_errlist[err].len = len; ngx_sys_errlist[err].data = p; } return NGX_OK; failed: err = errno; ngx_log_stderr(0, "malloc(%uz) failed (%d: %s)", len, err, strerror(err)); return NGX_ERROR; }可以看到此函数会动态创建一个包含NGX_SYS_NERR(此大小是在自动化脚本auto/unix生成的)个ngx_str_t元素的数组ngx_sys_errlist,用于记录错误码[0,NGX_SYS_NERR-1]对应的每一个错误信息描述。为什么这么做,其实在src/os/unix/ngx_errno.c中,作者已经有注释说明:
/* * The strerror() messages are copied because: * * 1) strerror() and strerror_r() functions are not Async-Signal-Safe, * therefore, they cannot be used in signal handlers; * * 2) a direct sys_errlist[] array may be used instead of these functions, * but Linux linker warns about its usage: * * warning: `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead * warning: `sys_nerr' is deprecated; use `strerror' or `strerror_r' instead * * causing false bug reports. */
作者解释为什么要把strerror()对应的错误信息描述复制一份,即ngx_sys_errlist。原因如下:
1)strerror()和strerror_r()函数都不是Async-Signal-Safe,因此,它们不能用在信号的处理函数中;
2)但是使用ngx_sys_errlist数组代替strerror()和strerror_r()函数,Linux上的链接器会产生告警;
使用ngx_sys_errlist数组实际是调用src/os/unix/ngx_errno.c中的ngx_strerror函数:
u_char * ngx_strerror(ngx_err_t err, u_char *errstr, size_t size) { ngx_str_t *msg; msg = ((ngx_uint_t) err < NGX_SYS_NERR) ? &ngx_sys_errlist[err]: &ngx_unknown_error; size = ngx_min(size, msg->len); return ngx_cpymem(errstr, msg->data, size); }
即,ngx_strerror函数会根据错误码入参,将ngx_sys_errlist数组中的对应的错误信息拷贝给调用者提供的buffer中,供调用者使用。
相关文章推荐
- nginx 源码学习——处理stale event
- nginx源码学习——命令行选项处理
- android 4.0.1源码编译,学习错误解决
- JavaScript学习笔记——错误处理
- Log4J学习【三十三】错误处理之ErrorHandler
- Nginx源码学习-双向链表(ngx_queue_t)实现及实例分析
- nginx 源码学习笔记(十三)——文件读写和配置文件读取
- DICOM医学图像处理:storescp.exe与storescu.exe源码剖析,学习C-STORE请求
- DICOM医学图形处理:storescp.exe与storescu.exe源码剖析,学习C-STORE请求(续)
- 【nginx源码学习与运用 五】双向链表ngx_queue_t
- nginx源码学习1 ngx_queue
- 【学习笔记】 javaScript错误处理
- 《Javascript高级程序设计》(第2版)学习笔记15--错误处理与调试
- PHP 学习笔记(四):高级教程:Cookies,Sessions,邮件,错误处理,异常处理,过滤器
- nginx 源码学习笔记(十一)——基本容器——ngx_list
- nginx 报499 502等错误处理
- nginx源码学习(六)
- nginx 源码学习笔记(六)——nginx基本数据结构
- 调试的艺术学习笔记--程序崩溃处理(段错误)
- swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)